forEach vs forEachOrdered in Java 8 Stream

JavaForeachJava 8Java Stream

Java Problem Overview


I understand that these methods differ the order of execution but in all my test I cannot achieve different order execution.

Example:

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));

Output:

forEach Demo
Output:AAA
Output:BBB
Output:CCC
forEachOrdered Demo
Output:AAA
Output:BBB
Output:CCC

Please provide examples when 2 methods will produce different outputs.

Java Solutions


Solution 1 - Java

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));

The second line will always output

Output:AAA
Output:BBB
Output:CCC

whereas the first one is not guaranted since the order is not kept. forEachOrdered will processes the elements of the stream in the order specified by its source, regardless of whether the stream is sequential or parallel.

Quoting from forEach Javadoc: >The behavior of this operation is explicitly nondeterministic. For parallel stream pipelines, this operation does not guarantee to respect the encounter order of the stream, as doing so would sacrifice the benefit of parallelism.

When the forEachOrdered Javadoc states (emphasis mine): >Performs an action for each element of this stream, in the encounter order of the stream if the stream has a defined encounter order.

Solution 2 - Java

Although forEach shorter and looks prettier, I'd suggest to use forEachOrdered in every place where order matters to explicitly specify this. For sequential streams the forEach seems to respect the order and even stream API internal code uses forEach (for stream which is known to be sequential) where it's semantically necessary to use forEachOrdered! Nevertheless you may later decide to change your stream to parallel and your code will be broken. Also when you use forEachOrdered the reader of your code sees the message: "the order matters here". Thus it documents your code better.

Note also that for parallel streams the forEach not only executed in non-determenistic order, but you can also have it executed simultaneously in different threads for different elements (which is not possible with forEachOrdered).

Finally both forEach/forEachOrdered are rarely useful. In most of the cases you actually need to produce some result, not just side-effect, thus operations like reduce or collect should be more suitable. Expressing reducing-by-nature operation via forEach is usually considered as a bad style.

Solution 3 - Java

forEach() method performs an action for each element of this stream. For parallel stream, this operation does not guarantee to maintain order of the stream.

forEachOrdered() method performs an action for each element of this stream, guaranteeing that each element is processed in encounter order for streams that have a defined encounter order.

take the example below:

    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));

Output:

****forEach without using parallel****

sushil mittal

****forEach with using parallel****

mihul issltat

****forEachOrdered with using parallel****

sushil mittal

Solution 4 - Java

We may lose the benefits of parallelism if we use forEachOrdered() with parallel Streams.

As we know, In parallel programming element will print parallelly if we use forEach() method. so the order will not be fixed. But In the use of forEachOrdered() fixed order in parallel Streams.

Stream.of("AAA","BBB","CCC").forEachOrdered(s->System.out.println("Output:"+s)); Output:AAA Output:BBB Output:CCC

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiongstackoverflowView Question on Stackoverflow
Solution 1 - JavaTunakiView Answer on Stackoverflow
Solution 2 - JavaTagir ValeevView Answer on Stackoverflow
Solution 3 - JavaSushil MittalView Answer on Stackoverflow
Solution 4 - JavavikashView Answer on Stackoverflow