web-dev-qa-db-ja.com

Java 8ストリームを使用して条件でリストを区切る方法

次のコードを検討してください。

_ List<Integer> odd = new ArrayList<Integer>();
 List<Integer> even = null;  
 List<Integer> myList = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
 even = myList.stream()
              .filter(item -> {
                   if(item%2 == 0) { return true;}
                   else { 
                           odd.add(item); 
                           return false;
                   }
              })
              .collect(Collectors.toList());
_

ここで私がしようとしていることは、リストから別のリストに偶数と奇数の値を取得することです。

ストリームfilter()メソッドは、偶数項目に対してtrueを返し、ストリームコレクターがそれらを収集します。
奇数の場合、フィルターはfalseを返し、アイテムはコレクターに到達しません。

したがって、そのような奇数を、前にelseブロックの下に作成した別のリストに追加しています。

これはストリームを操作するエレガントな方法ではないことを知っています。たとえば、並列ストリームを使用すると、奇数リストにスレッドセーフの問題が発生します。パフォーマンス上の理由(O(n)である必要があります)のため、異なるフィルターで複数回実行することはできません。

これは1つの使用例の単なる例であり、リストには任意のオブジェクトを含めることができ、フィルター内のラムダはいくつかのロジックに基づいてそれらを別々のリストに分離する必要があります。

簡単に言うと、リストから、いくつかの基準に基づいて分離されたアイテムを含む複数のリストを作成します。

ストリームがなければ、forループを実行して単純なif-elseを実行し、条件に基づいてアイテムを収集するだけです。

17
Roy

このリストの要素(数値)を偶数と奇数に分離する方法の例を次に示します。

List<Integer> myList = Arrays.asList(1,2,3,4,5,6,7,8,9,10);

Map<Boolean, List<Integer>> evenAndOdds = myList.stream()
        .collect(partitioningBy(i -> i % 2 == 0));

次のような偶数/奇数のリストが表示されます(どちらのリストも空の場合があります)。

List<Integer> even = evenAndOdds.get(true);
List<Integer> odd = evenAndOdds.get(false);

partitioningByで必要なロジックを含む任意のラムダを渡すことができます。

33