As far as I'm aware, in parallel streams, methods such findFirst
, skip
, limit
and etc. keep their behaviour as long as stream is ordered (which is by default) whether is't parallel or not. So I was wondering why forEach
method is different. I gave it some thought, but I just could not understand the neccessity of defining forEachOrdered
method, when it could have been more easier and less surprising to make forEach
ordered by default, then call unordered
on stream instance and that's it, no need to define new method.
Unfortunately my practical experience with Java 8 is quite limited at this point, so I would really appreciate if someone could explain me reasons for this architectural decision, maybe with some simple examples/use-cases to show me what could go wrong otherwise.
Just to make it clear, I'm not asking about this: forEach vs forEachOrdered in Java 8 Stream. I'm perfectly aware how those methods work and differences between them. What I'm asking about is practical reasons for architectural decision made by Oracle.
Defining a method forEach
that would preserve order and unordered
that would break it, would complicated things IMO; simply because unordered
does nothing more than setting a flag in the stream api internals and the flag checking would have to be performed or enforced based on some conditions.
So let's say you would do:
someStream()
.unordered()
.forEach(System.out::println)
In this case, your proposal is to not print elements in any order, thus enforcing unordered
here. But what if we did:
someSet().stream()
.unordered()
.forEach(System.out::println)
In this case would you want unordered
to be enforced? After all, the source of a stream is a Set
, which has no order, so in this case, enforcing unordered
is just useless; but this means additional tests on the source of the stream internally. This can get quite tricky and complicated (as it already is btw).
To make it simpler there were two method defined, that clearly stipulate what they will do; and this is on par for example with findFirst
vs findAny
or even Optional::isPresent
and Optional::isEmpty
(added in java-11).
When you process elements of a Stream in parallel, you simply should not expect any guarantees on order.
The whole idea is that multiple threads work on different elements of that stream. They progress individually, therefore the order of processing is not predictable. It is indeterministic, aka random.
I could imagine that the people implementing that interface purposely give you random order, to make it really clear that you shall not expect any distinct order when using parallel streams.
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