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.
Conclusion: If you have a small list; for loops perform better, if you have a huge list; a parallel stream will perform better. And since parallel streams have quite a bit of overhead, it is not advised to use these unless you are sure it is worth the overhead.
The reason for the different results is that forEach() used directly on the list uses the custom iterator, while stream(). forEach() simply takes elements one by one from the list, ignoring the iterator.
parallel foreach() Works on multithreading concept: The only difference between stream(). forEach() and parallel foreach() is the multithreading feature given in the parallel forEach(). This is way faster that foreach() and stream.
Stream forEach() method in Java with examplesStream forEach(Consumer action) performs an action for each element of the stream. Stream forEach(Consumer action) is a terminal operation i.e, it may traverse the stream to produce a result or a side-effect.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With