Hierfür kann ein Kollektor verwendet werden.
- Verwenden Sie für zwei Kategorien
Collectors.partitioningBy()
Factory.
Dadurch wird ein Map
Von Boolean
bis erstellt List
und Elemente basierend auf a in die eine oder andere Liste eingefügt Predicate
.
Hinweis: Da der Stream als Ganzes verbraucht werden muss, kann dies bei unendlichen Streams nicht funktionieren. Und weil der Stream sowieso verbraucht wird, werden sie bei dieser Methode einfach in Listen eingefügt, anstatt einen neuen Stream mit Speicher zu erstellen. Sie können diese Listen jederzeit streamen, wenn Sie Streams als Ausgabe benötigen.
Außerdem ist der Iterator nicht erforderlich, auch nicht in dem von Ihnen bereitgestellten Nur-Kopf-Beispiel.
- Die binäre Aufteilung sieht folgendermaßen aus:
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());
- Verwenden Sie für weitere Kategorien eine
Collectors.groupingBy()
Factory.
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());
Falls die Streams nicht sind Stream
, aber einer der primitiven Streams wie IntStream
, dann ist diese .collect(Collectors)
Methode nicht verfügbar. Sie müssen dies manuell ohne Sammlerfabrik tun. Die Implementierung sieht folgendermaßen aus:
[Beispiel 2.0 seit 2020-04-16]
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 ));
});
In diesem Beispiel initialisiere ich die ArrayLists mit der vollen Größe der ursprünglichen Sammlung (falls dies überhaupt bekannt ist). Dies verhindert Größenänderungsereignisse auch im schlimmsten Fall, kann jedoch möglicherweise 2 * N * T-Speicherplatz verschlingen (N = anfängliche Anzahl von Elementen, T = Anzahl von Threads). Um den Platz gegen die Geschwindigkeit auszutauschen, können Sie ihn weglassen oder Ihre am besten fundierte Vermutung verwenden, z. B. die erwartete höchste Anzahl von Elementen in einer Partition (normalerweise etwas mehr als N / 2 für eine ausgeglichene Aufteilung).
Ich hoffe, ich beleidige niemanden mit einer Java 9-Methode. Informationen zur Java 8-Version finden Sie im Bearbeitungsverlauf.
Stream
in mehrereStream
s zu konvertieren , obwohl ich denke, dass Leute, die diese Frage erreicht haben, tatsächlich nach dem Weg suchen, dies zu erreichen, unabhängig von einer solchen Einschränkung, die Marks Antwort ist. Dies kann daran liegen, dass die Frage im Titel nicht mit der in der Beschreibung übereinstimmt .