Encomende operações terminais amigáveis / hostis contra fluxos paralelos / sequenciais vs ordenados / não ordenados
Inspirado poressa questão, Comecei a jogar com fluxos ordenados vs não ordenados, fluxos paralelos versus sequenciais e operações de terminal que respeitam operações de ordem versus terminal que não o respeitam.
Em uma resposta à pergunta vinculada, um código semelhante a este é mostrado:
List<Integer> ordered = Arrays.asList(
1, 2, 3, 4, 4, 3, 2, 1, 1, 2, 3, 4, 4, 3, 2, 1, 1, 2, 3, 4);
List<Integer> result = new CopyOnWriteArrayList<>();
ordered.parallelStream().forEach(result::add);
System.out.println(ordered);
System.out.println(result);
E as listas são realmente diferentes. ounordered
lista até muda de uma execução para outra, mostrando que o resultado é realmente não determinístico.
Então, eu criei este outro exemplo:
CopyOnWriteArrayList<Integer> result2 = ordered.parallelStream()
.unordered()
.collect(Collectors.toCollection(CopyOnWriteArrayList::new));
System.out.println(ordered);
System.out.println(result2);
E eu esperava ver resultados semelhantes, pois o fluxo é paralelo e desordenado (talvezunordered()
é redundante, pois já é paralelo). No entanto, a lista resultante é ordenada, ou seja, é igual à lista de fontes.
Então, minha pergunta é por que a lista coletada é ordenada? Fazcollect
respeitar sempre a ordem do encontro, mesmo para fluxos paralelos e não ordenados? É o específicoCollectors.toCollection(...)
colecionador aquele que força a ordem do encontro?