Entiendo que estos métodos difieren en el orden de ejecución, pero en todas mis pruebas no puedo lograr una ejecución de órdenes diferente.
Ejemplo:
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));
Salida:
forEach Demo
Output:AAA
Output:BBB
Output:CCC
forEachOrdered Demo
Output:AAA
Output:BBB
Output:CCC
Proporcione ejemplos en los que dos métodos producirán resultados diferentes.
java
foreach
java-8
java-stream
gstackoverflow
fuente
fuente
Respuestas:
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));
La segunda línea siempre saldrá
mientras que el primero no está garantizado ya que no se mantiene el pedido.
forEachOrdered
procesará los elementos de la secuencia en el orden especificado por su fuente, independientemente de si la secuencia es secuencial o paralela.Citando de
forEach
Javadoc:Cuando el
forEachOrdered
Javadoc dice (énfasis mío):fuente
forEachOrdered
conparallel
?Aunque es
forEach
más corto y se ve más bonito, sugeriría usarloforEachOrdered
en todos los lugares donde el orden importa para especificar esto explícitamente. Para las transmisiones secuenciales,forEach
parece respetar el orden e incluso los usos del código interno de la API de transmisiónforEach
(para la transmisión que se sabe que es secuencial) donde es semánticamente necesario usarforEachOrdered
. Sin embargo, más tarde puede decidir cambiar su flujo a paralelo y su código se romperá. También cuando usaforEachOrdered
el lector de su código ve el mensaje: "el orden importa aquí". Por lo tanto, documenta mejor su código.Tenga en cuenta también que para los flujos paralelos,
forEach
no solo se ejecuta en orden no determenístico, sino que también puede ejecutarlo simultáneamente en diferentes hilos para diferentes elementos (lo que no es posible conforEachOrdered
).Finalmente, ambos
forEach
/forEachOrdered
rara vez son útiles. En la mayoría de los casos, es necesario producir algún resultado, no solo un efecto secundario, por lo que las operaciones comoreduce
ocollect
deberían ser más adecuadas. Expresar la operación de reducción por naturaleza a través deforEach
generalmente se considera un mal estilo.fuente
forEachOrdered
en ese código?flatMap
). Puede solicitarse, por lo que debe colocarse en el flujo resultante en el mismo orden.Stream.of("a", "b", "c").flatMap(s -> Stream.of("1", "2", "3").map(s::concat)).spliterator().hasCharacteristics(Spliterator.ORDERED)
devuelve verdadero, por lo que se debe determinar el orden de la secuencia resultante. Si cree que la documentación de JDK debería decir explícitamente sobre esto, no dude en enviar un error.forEach()
El método realiza una acción para cada elemento de esta secuencia. Para flujo paralelo, esta operación no garantiza mantener el orden del flujo.forEachOrdered()
El método realiza una acción para cada elemento de este flujo, garantizando que cada elemento se procesa en orden de encuentro para los flujos que tienen un orden de encuentro definido.tome el ejemplo siguiente:
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));
Salida:
fuente