Se puede usar un colector para esto.
- Para dos categorías, use la
Collectors.partitioningBy()
fábrica.
Esto creará un Map
desde Boolean
hasta List
y colocará elementos en una u otra lista según un Predicate
.
Nota: Dado que la transmisión debe consumirse completa, esto no puede funcionar en transmisiones infinitas. Y debido a que el flujo se consume de todos modos, este método simplemente los coloca en listas en lugar de crear un nuevo flujo con memoria. Siempre puede transmitir esas listas si necesita transmisiones como salida.
Además, no es necesario el iterador, ni siquiera en el ejemplo de solo cabezas que proporcionó.
- La división binaria se ve así:
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());
- Para más categorías, use una
Collectors.groupingBy()
fábrica.
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());
En caso de que los flujos no lo sean Stream
, pero uno de los flujos primitivos parezca IntStream
, entonces este .collect(Collectors)
método no está disponible. Tendrás que hacerlo de forma manual sin una fábrica de colectores. Su implementación se ve así:
[Ejemplo 2.0 desde 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 ));
});
En este ejemplo, inicializo las ArrayLists con el tamaño completo de la colección inicial (si esto se conoce). Esto evita eventos de cambio de tamaño incluso en el peor de los casos, pero potencialmente puede engullir 2 * N * T espacio (N = número inicial de elementos, T = número de subprocesos). Para cambiar el espacio por la velocidad, puede omitirlo o usar su conjetura mejor educada, como el mayor número esperado de elementos en una partición (generalmente un poco más de N / 2 para una división equilibrada).
Espero no ofender a nadie usando un método Java 9. Para la versión Java 8, mire el historial de edición.
Stream
a múltiplesStream
s sin conversión intermedia , aunque creo que las personas que llegaron a esta pregunta en realidad están buscando la manera de lograrlo, independientemente de esa restricción, que es la respuesta de Mark. Esto puede deberse al hecho de que la pregunta en el título no es la misma que en la descripción .