Esta resposta fornece uma implementação para particionar um IntStream:
IntStream intStream = IntStream.iterate(0, i -> i + 1).limit(1000000);
Predicate<Integer> p = x -> r.nextBoolean();
Map<Boolean, List<Integer>> groups = intStream.collect(() -> {
Map<Boolean, List<Integer>> map = new HashMap<>();
map.put(false, new ArrayList<>());
map.put(true, new ArrayList<>());
return map;
}, (map, x) -> {
boolean partition = p.test(x);
List<Integer> list = map.get(partition);
list.add(x);
}, (map1, map2) -> {
map1.get(false).addAll(map2.get(false));
map1.get(true).addAll(map2.get(true));
});
System.out.println(groups.get(false).size());
System.out.println(groups.get(true).size());
Mas sua edição menciona que essa implementação não é segura para threads. Até onde posso ver, no entanto, o coletor cria um separado HashMap<List<Integer>>
para cada thread em um fluxo paralelo. Portanto, cada mapa é confinado a um único encadeamento. A função de particionamento também está restrita a um único encadeamento. A função de mesclagem mescla os resultados de vários threads, mas até onde eu sei, a estrutura do fluxo garante que a mesclagem seja feita de maneira segura. Então, minha pergunta: essa solução realmente não é segura para threads?
BTW: A resposta fornece uma solução mais elegante de qualquer maneira ( Stream<Integer> stream = intStream.boxed();
etc), mas eu ainda gosto de saber.
PS: Gostaria de adicionar esta pergunta como um comentário à postagem original, mas nem tenho reputação de adicionar comentários ...: |
De acordo com a documentação do Oracles
Assim como reduzir (int, IntBinaryOperator), as operações de coleta podem ser paralelizadas sem exigir sincronização adicional.
Parece que sua intuição está certa de que isso é seguro para threads.
Este artigo é coletado da Internet.
Se houver alguma infração, entre em [email protected] Delete.
deixe-me dizer algumas palavras