これにはコレクターを使用できます。
- 2つのカテゴリの場合は、
Collectors.partitioningBy()
factoryを使用します。
これによりMap
from が作成さBoolean
れList
、に基づいてアイテムがいずれかのリストに配置されますPredicate
。
注:ストリーム全体を消費する必要があるため、これは無限ストリームでは機能しません。とにかくストリームが消費されるので、このメソッドは、メモリ付きの新しいストリームを作成するのではなく、単にリストに入れます。出力としてストリームが必要な場合は、いつでもこれらのリストをストリーミングできます。
また、提供したヘッドのみの例でも、イテレータは必要ありません。
Random r = new Random();
Map<Boolean, List<String>> groups = stream
.collect(Collectors.partitioningBy(x -> r.nextBoolean()));
System.out.println(groups.get(false).size());
System.out.println(groups.get(true).size());
- その他のカテゴリについては、
Collectors.groupingBy()
ファクトリを使用してください。
Map<Object, List<String>> groups = stream
.collect(Collectors.groupingBy(x -> r.nextInt(3)));
System.out.println(groups.get(0).size());
System.out.println(groups.get(1).size());
System.out.println(groups.get(2).size());
ストリームがではなくStream
、のようなプリミティブストリームの1つである場合、IntStream
この.collect(Collectors)
メソッドは使用できません。あなたはコレクターファクトリーなしで手動でそれをしなければならないでしょう。その実装は次のようになります。
[2020-04-16以降の例2.0]
IntStream intStream = IntStream.iterate(0, i -> i + 1).limit(100000).parallel();
IntPredicate predicate = ignored -> r.nextBoolean();
Map<Boolean, List<Integer>> groups = intStream.collect(
() -> Map.of(false, new ArrayList<>(100000),
true , new ArrayList<>(100000)),
(map, value) -> map.get(predicate.test(value)).add(value),
(map1, map2) -> {
map1.get(false).addAll(map2.get(false));
map1.get(true ).addAll(map2.get(true ));
});
この例では、最初のコレクションのフルサイズでArrayListを初期化します(これがまったくわかっている場合)。これにより、最悪の場合でもイベントのサイズ変更が防止されますが、2 * N * Tのスペース(N =要素の初期数、T =スレッド数)が乱れる可能性があります。スペースと速度をトレードオフするには、スペースを省略するか、1つのパーティションで予想される要素の最大数(通常、バランスの取れた分割の場合はN / 2を超える)など、経験に基づいた推測を使用します。
私はJava 9メソッドを使用して他人を怒らせないことを望みます。Java 8バージョンについては、編集履歴をご覧ください。
Stream
複数Stream
のに変換する可能性に焦点を当てていますが、この質問に到達した人々は、マークの答えであるそのような制約に関係なく、実際に達成する方法を探していると思います。これは、タイトルの質問が説明の質問と同じではないためと考えられます。