Eu entendo que esses métodos diferem na ordem de execução, mas em todos os meus testes não consigo obter execução de ordem diferente.
Exemplo:
System.out.println("forEach Demo");
Stream.of("AAA","BBB","CCC").forEach(s->System.out.println("Output:"+s));
System.out.println("forEachOrdered Demo");
Stream.of("AAA","BBB","CCC").forEachOrdered(s->System.out.println("Output:"+s));
Resultado:
forEach Demo
Output:AAA
Output:BBB
Output:CCC
forEachOrdered Demo
Output:AAA
Output:BBB
Output:CCC
Forneça exemplos quando 2 métodos produzirão resultados diferentes.
java
foreach
java-8
java-stream
gstackoverflow
fonte
fonte
Respostas:
Stream.of("AAA","BBB","CCC").parallel().forEach(s->System.out.println("Output:"+s)); Stream.of("AAA","BBB","CCC").parallel().forEachOrdered(s->System.out.println("Output:"+s));
A segunda linha sempre produzirá
enquanto o primeiro não é garantido, pois a ordem não é mantida.
forEachOrdered
irá processar os elementos do fluxo na ordem especificada por sua fonte, independentemente de o fluxo ser sequencial ou paralelo.Citando de
forEach
Javadoc:Quando o
forEachOrdered
Javadoc afirma (ênfase minha):fonte
forEachOrdered
comparallel
?Embora
forEach
mais curto e pareça mais bonito, eu sugiro usarforEachOrdered
em todos os lugares onde a ordem é importante para especificar isso explicitamente. Para fluxos sequenciais,forEach
parece respeitar a ordem e até mesmo usar o código interno da API de fluxoforEach
(para fluxos sabidamente sequenciais) onde é semanticamente necessário usarforEachOrdered
! No entanto, você pode decidir posteriormente alterar seu fluxo para paralelo e seu código será quebrado. Além disso, quando você usaforEachOrdered
o leitor de seu código, vê a mensagem: "a ordem é importante aqui". Assim, documenta melhor o seu código.Observe também que, para fluxos paralelos,
forEach
não apenas é executado em ordem não determinística, mas também pode ser executado simultaneamente em diferentes threads para diferentes elementos (o que não é possível comforEachOrdered
).Finalmente, ambos
forEach
/forEachOrdered
raramente são úteis. Na maioria dos casos, você realmente precisa produzir algum resultado, não apenas efeito colateral, portanto, operações semelhantesreduce
oucollect
devem ser mais adequadas. Expressar a operação de redução natural viaforEach
geralmente é considerado um estilo ruim.fonte
forEachOrdered
nesse código?flatMap
). Ele pode ser ordenado, portanto, deve ser colocado no fluxo resultante na mesma ordem.Stream.of("a", "b", "c").flatMap(s -> Stream.of("1", "2", "3").map(s::concat)).spliterator().hasCharacteristics(Spliterator.ORDERED)
retorna true, portanto, a ordem do fluxo resultante deve ser determinada. Se você acha que a documentação do JDK deve dizer explicitamente sobre isso, sinta-se à vontade para enviar um bug.forEach()
método executa uma ação para cada elemento deste fluxo. Para fluxo paralelo, esta operação não garante a manutenção da ordem do fluxo.forEachOrdered()
O método executa uma ação para cada elemento desse fluxo, garantindo que cada elemento seja processado em ordem de encontro para fluxos que tenham uma ordem de encontro definida.veja o exemplo abaixo:
String str = "sushil mittal"; System.out.println("****forEach without using parallel****"); str.chars().forEach(s -> System.out.print((char) s)); System.out.println("\n****forEach with using parallel****"); str.chars().parallel().forEach(s -> System.out.print((char) s)); System.out.println("\n****forEachOrdered with using parallel****"); str.chars().parallel().forEachOrdered(s -> System.out.print((char) s));
Resultado:
fonte