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レポ]にあります。