Javaでコレクションをフィルタリングする方法
1.概要
この短いチュートリアルでは、
Javaでコレクションをフィルタリングする
さまざまな方法、つまり特定の条件を満たすすべての項目を見つける方法について説明します。
これは実質的にあらゆるJavaアプリケーションに存在する基本的なタスクです。
このため、この目的のための機能を提供するライブラリの数は膨大です。
特にこのチュートリアルでは、次のことを説明します。
-
Java 8 Streamの
filter()
関数 -
Java 9
フィルタ
コレクタ -
関連する
Eclipseコレクション
API -
Apacheの
CollectionUtils filter()
メソッド -
グアバの
Collections2 filter()
アプローチ
2. Streamsを使う
Java 8が導入されて以来、https://www.baeldung.com/java-8-streams-introduction[Streams]は、データの集まりを処理しなければならないほとんどの場合において重要な役割を果たしてきました。
したがって、これはJavaで構築されており、追加の依存関係を必要としないため、これはほとんどの場合に推奨されるアプローチです。
2.1.
Streams
を使ったコレクションのフィルタリング
わかりやすくするために、すべての例で、
Collection__
値から偶数のみを取得するメソッドを作成することを目的とします。
したがって、各項目の評価に使用する条件を「
value%2 == 0
」と表現できます。
すべての場合において、この条件を
Predicate
オブジェクトとして定義する必要があります。
public Collection<Integer> findEvenNumbers(Collection<Integer> baseCollection) {
Predicate<Integer> streamsPredicate = item -> item % 2 == 0;
return baseCollection.stream()
.filter(streamsPredicate)
.collect(Collectors.toList());
}
このチュートリアルで分析する各ライブラリはそれぞれ独自の
__Preicate
____implementation ** を提供していますが、それでもなお、それらはすべて関数インターフェイスとして定義されているため、Lambda関数を使用してそれらを宣言できます。
この場合は、要素を
List
に蓄積する、Javaによって提供された定義済みの
__Collector
__を使用しましたが、https://www.baeldung.com/java-8-collectorsの前の記事で説明したように、他のものを使用することもできます。]。
2.2. Java 9でコレクションをグループ化した後のフィルタリング
ストリームにより、https://www.baeldung.com/java-groupingby-collector[
groupingBy collector
]を使用してアイテムを集計できます。
しかし、前のセクションで行ったようにフィルタリングすると、一部の要素はこのコレクターが機能するようになる前の早い段階で破棄される可能性があります。
このため、
coltering
collectorは、サブコレクションをグループ化した後に処理することを目的として、Java 9で導入されました。
この例に従って、奇数を除外する前に、各整数の桁数に基づいてコレクションをグループ化したいとします。
public Map<Integer, List<Integer>> findEvenNumbersAfterGrouping(
Collection<Integer> baseCollection) {
Function<Integer, Integer> getQuantityOfDigits = item -> (int) Math.log10(item) + 1;
return baseCollection.stream()
.collect(groupingBy(
getQuantityOfDigits,
filtering(item -> item % 2 == 0, toList())));
}
つまり、このコレクターを使用すると、空の値のエントリになる可能性がありますが、グループ化する前にフィルター処理すると、コレクターはそのようなエントリを作成しません。
もちろん、要件に基づいてアプローチを選択します。
3.
Eclipseコレクション
を使う
-
アプリケーションがJava 8をサポートしていないため、またはJavaが提供していない強力な機能を利用したいために、他のサードパーティ製ライブラリを使用して目的を達成することもできます。
そのようなことが
Eclipse Collections
のケースであり、これは新しいパラダイムについていくために努力し、すべての最新のJavaリリースによって導入された変更を発展させそして受け入れます。
このライブラリーによって提供される機能のより広い知識を得るために私達のhttps://www.baeldung.com/eclipse-collections[Eclipse Collections入門記事]を調べることから始めることができます。
3.1. 依存関係
まず、プロジェクトの
pom.xml
に次の依存関係を追加します。
<dependency>
<groupId>org.eclipse.collections</groupId>
<artifactId>eclipse-collections</artifactId>
<version>9.2.0</version>
</dependency>
eclipse-collections
にはすべてが含まれます必要なデータ構造体インターフェースとAPI自体。
3.2.
Eclipseコレクション
を使用したコレクションのフィルタリング
MutableList
のようなデータ構造の1つにeclipseのフィルター機能を使用しましょう。
public Collection<Integer> findEvenNumbers(Collection<Integer> baseCollection) {
Predicate<Integer> eclipsePredicate
= item -> item % 2 == 0;
Collection<Integer> filteredList = Lists.mutable
.ofAll(baseCollection)
.select(eclipsePredicate);
return filteredList;
}
別の方法として、
Iterate
の
__select()
staticメソッドを使用して
filteredList__オブジェクトを定義することもできます。
Collection<Integer> filteredList
= Iterate.select(baseCollection, eclipsePredicate);
4. Apacheの
CollectionUtils
を使う
Apacheの
CollectionUtils
ライブラリを使い始めるには、https://www.baeldung.com/apache-commons-collection-utils[この短いチュートリアル]を調べて、その用途を説明してください。
ただし、このチュートリアルでは、filter()の実装に焦点を当てます。
4.1. 依存関係
まず、
pom.xml
ファイルに次の依存関係が必要です。
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.2</version>
</dependency>
3.2.
CollectionUtils
を使用したコレクションのフィルタリング
これで
CollectonUtils
メソッドを使用する準備が整いました。
public Collection<Integer> findEvenNumbers(Collection<Integer> baseCollection) {
Predicate<Integer> apachePredicate = item -> item % 2 == 0;
CollectionUtils.filter(baseCollection, apachePredicate);
return baseCollection;
}
このメソッドは、条件に一致しないすべてのアイテムを削除することによって
baseCollection
を変更することを考慮する必要があります。
これは、基本コレクションが可変でなければならないことを意味します。
4. Guavaの
Collections2
を使う
これまでと同様に、この件に関するさらなる情報については、以前の投稿https://www.baeldung.com/guava-filter-and-transform-a-collection[Guavaでのコレクションのフィルタリングと変換]を参照してください。
3.1. 依存関係
まずhttps://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22com.google.guava%22%20AND%20a%3A%22guava%22[th依存関係]を私たちのサイトに追加します
pom.xml
ファイル:
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>25.1-jre</version>
</dependency>
3.2.
Collections2
を使用したコレクションのフィルタリング
ご覧のとおり、このアプローチは前のセクションで説明したものとほぼ同じです。
public Collection<Integer> findEvenNumbers(Collection<Integer> baseCollection) {
Predicate<Integer> guavaPredicate = item -> item % 2 == 0;
return Collections2.filter(baseCollection, guavaPredicate);
}
繰り返しますが、ここではGuava固有の
Predicate
オブジェクトを定義します。
この場合、Guavaは
baseCollection
を変更するのではなく、新しいコレクションを生成するので、不変のコレクションを入力として使用できます。
5.まとめ
まとめると、Javaでコレクションをフィルタリングする方法はたくさんあります。
通常、Streamsが推奨される方法ですが、他のライブラリによって提供される機能を知っていることを忘れないでください。
特に古いJavaバージョンをサポートする必要があるならば。ただし、その場合は、チュートリアルで使用されているラムダなどの最近のJava機能を匿名クラスに置き換える必要があります。
いつものように、このチュートリアルに示されている例はすべてhttps://github.com/eugenp/tutorials/tree/master/core-java-collections[Githubレポ]にあります。