foreachordered ejemplo array java foreach order java-8 java-stream

ejemplo - forEach vs forEachOrdered en Java 8 Stream



java arraylist foreach (3)

Entiendo que estos métodos difieren en el orden de ejecución, pero en todas mis pruebas no puedo lograr una ejecución de orden 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 cuando 2 métodos produzcan resultados diferentes.


Aunque forEach más corto y parece más bonito, sugeriría usar forEachOrdered en todos los lugares donde el orden es importante para especificar explícitamente esto. Para secuencias secuenciales, forEach parece respetar el orden e incluso la secuencia de código interno de API uses forEach (para secuencias que se sabe que son secuenciales) donde es semánticamente necesario usar forEachOrdered ! Sin embargo, más tarde puede decidir cambiar su transmisión a paralelo y su código se romperá. Además, cuando utiliza forEachOrdered 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 flujos paralelos, forEach no solo se ejecuta en un orden no determinista, sino que también puede ejecutarse simultáneamente en diferentes subprocesos para diferentes elementos (lo que no es posible con forEachOrdered ).

Finalmente, tanto forEach / forEachOrdered rara vez son útiles. En la mayoría de los casos, realmente necesita producir algún resultado, no solo efectos secundarios, por lo tanto, las operaciones como reduce o collect deberían ser más adecuadas. Expresar la operación de reducción por naturaleza a través de forEach generalmente se considera un mal estilo.


El método forEach () realiza una acción para cada elemento de esta secuencia. Para la transmisión en paralelo, esta operación no garantiza mantener el orden de la transmisión.

El método forEachOrdered () realiza una acción para cada elemento de esta secuencia, garantizando que cada elemento se procese en orden de encuentro para las secuencias que tienen un orden de encuentro definido.

tome el siguiente ejemplo:

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:

**** para cada uno sin usar paralelo ****

sushil mittal

**** para cada uno con el uso de paralelo ****

mihul issltat

**** forEachOrdered con el uso de paralelo ****

sushil mittal


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á

Output:AAA Output:BBB Output:CCC

mientras que el primero no está garantizado ya que el orden no se mantiene. 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:

El comportamiento de esta operación es explícitamente no determinista. Para las tuberías de flujo paralelo, esta operación no garantiza respetar el orden de encuentro del flujo, ya que al hacerlo se sacrificaría el beneficio del paralelismo.

Cuando el Javadoc forEachOrdered establece (el énfasis es mío):

Realiza una acción para cada elemento de esta secuencia, en el orden de encuentro de la secuencia si la secuencia tiene un orden de encuentro definido.