In java 8 documentation (doc order stream), one can see this :
if [a stream] is not ordered, repeated execution might produce different results.
The obvious answer is that whenever you use unordered
you should get different results. For example using this:
int first = Arrays.asList(1, 2, 3, 4).stream()
.unordered()
.parallel()
.findFirst()
.get();
System.out.println(first);
should produce a result that is not always 1. Because the stream is unordered, so any result out of [1,2,3,4]
is possible.
In java-8 this is not true, the stream pipeline does not take that unordered
into account:
@Override
public <P_IN> O evaluateParallel(PipelineHelper<T> helper,
Spliterator<P_IN> spliterator) {
return new FindTask<>(this, helper, spliterator).invoke();
}
But things have change in java-9:
@Override
public <P_IN> O evaluateParallel(PipelineHelper<T> helper,
Spliterator<P_IN> spliterator) {
// This takes into account the upstream ops flags and the terminal
// op flags and therefore takes into account findFirst or findAny
boolean mustFindFirst = StreamOpFlag.ORDERED.isKnown(helper.getStreamAndOpFlags());
return new FindTask<>(this, mustFindFirst, helper, spliterator).invoke();
}
So running the same code under java-9 multiple times will produce a different result.
There are operations that are already unordered
like Stream#generate
and Stream#forEach
.
the documentation of Stream#forEach is already said as below:
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.
so the following test should be pass:
List<Integer> ordered = Arrays.asList(1, 2, 3, 4);
List<Integer> unordered = new CopyOnWriteArrayList<>();
ordered.stream().parallel().forEach(unordered::add);
assertThat(unordered, not(equalTo(ordered)));
and the operation Stream#findAny also is nondeterministic.