Un collezionista può essere utilizzato per questo.
- Per due categorie, utilizzare
Collectors.partitioningBy()
factory.
Ciò creerà un Map
da Boolean
a List
e inserirà gli elementi in uno o l'altro elenco in base a a Predicate
.
Nota: poiché il flusso deve essere consumato intero, questo non può funzionare su flussi infiniti. E poiché lo stream viene comunque consumato, questo metodo li inserisce semplicemente negli elenchi invece di creare un nuovo stream con memoria. È sempre possibile eseguire lo streaming di tali elenchi se si richiedono flussi come output.
Inoltre, non è necessario l'iteratore, nemmeno nell'esempio solo testa che hai fornito.
- La divisione binaria si presenta così:
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());
- Per più categorie, utilizzare una
Collectors.groupingBy()
fabbrica.
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());
Nel caso in cui i flussi non lo siano Stream
, ma piace uno dei flussi primitivi IntStream
, questo .collect(Collectors)
metodo non è disponibile. Dovrai farlo manualmente senza una fabbrica di collezionisti. La sua implementazione è simile alla seguente:
[Esempio 2.0 dal 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 questo esempio, inizializzo gli ArrayLists con l'intera dimensione della raccolta iniziale (se questo è noto). Questo impedisce gli eventi di ridimensionamento anche nello scenario peggiore, ma può potenzialmente inghiottire 2 * N * T spazio (N = numero iniziale di elementi, T = numero di thread). Per compensare lo spazio per la velocità, puoi lasciarlo fuori o usare la tua ipotesi più istruita, come il numero più alto previsto di elementi in una partizione (in genere appena sopra N / 2 per una divisione bilanciata).
Spero di non offendere nessuno usando un metodo Java 9. Per la versione Java 8, guarda la cronologia delle modifiche.
Stream
a piùStream
s senza conversione intermedia , anche se penso che le persone che hanno raggiunto questa domanda sono in realtà cercando il modo per raggiungere in modo indipendentemente da tale vincolo, che è la risposta di Marco. Ciò può essere dovuto al fatto che la domanda nel titolo non è uguale a quella nella descrizione .