Um coletor pode ser usado para isso.
- Para duas categorias, use
Collectors.partitioningBy()
factory.
Isso criará um Map
de Boolean
para List
e colocará itens em uma ou outra lista com base em a Predicate
.
Nota: Como o fluxo precisa ser consumido inteiro, isso não pode funcionar em fluxos infinitos. E como o fluxo é consumido de qualquer maneira, esse método simplesmente os coloca em Listas, em vez de criar um novo fluxo com memória. Você sempre pode transmitir essas listas se precisar de fluxos como saída.
Além disso, não há necessidade do iterador, nem mesmo no exemplo somente de cabeçote que você forneceu.
- A divisão binária é assim:
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 mais categorias, use uma
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());
Caso os fluxos não sejam Stream
, mas um dos fluxos primitivos IntStream
, esse .collect(Collectors)
método não estará disponível. Você terá que fazer isso da maneira manual sem uma fábrica de colecionadores. Sua implementação é assim:
[Exemplo 2.0 desde 16/04 2020]
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 ));
});
Neste exemplo, inicializo o ArrayLists com o tamanho total da coleção inicial (se é que isso é conhecido). Isso evita eventos de redimensionamento, mesmo no pior cenário, mas pode potencialmente devorar 2 * N * T de espaço (N = número inicial de elementos, T = número de encadeamentos). Para trocar o espaço pela velocidade, você pode deixá-lo de fora ou usar seu palpite melhor, como o maior número esperado de elementos em uma partição (normalmente um pouco acima de N / 2 para uma divisão equilibrada).
Espero não ofender ninguém usando o método Java 9. Para a versão do Java 8, consulte o histórico de edições.
Stream
em múltiplosStream
s sem conversão intermediária , embora eu ache que as pessoas que chegaram a essa pergunta estão realmente procurando o caminho para alcançá-lo, independentemente de tal restrição, que é a resposta de Mark. Isso pode ser devido ao fato de a pergunta no título não ser a mesma da descrição .