Reputation: 69259
When computing Cartesian Products using streams, I can produce them in parallel, and consume them in order, which the following code demonstrates:
int min = 0;
int max = 9;
Supplier<IntStream> supplier = () -> IntStream.rangeClosed(min, max).parallel();
supplier.get()
.flatMap(a -> supplier.get().map(b -> a * b))
.forEachOrdered(System.out::println);
This will print everything perfectly in order, now consider the following code where I want to add it to a list, while preserving the order.
int min = 0;
int max = 9;
Supplier<IntStream> supplier = () -> IntStream.rangeClosed(min, max).parallel();
List<Integer> list = supplier.get()
.flatMap(a -> supplier.get().map(b -> a * b))
.boxed()
.collect(Collectors.toList());
list.forEach(System.out::println);
Now it does not print in order!
This is understandable given that I nowhere demand that the order should be preserved.
Now the question: Is there a way to collect()
or is there a Collector
that preserves order?
Upvotes: 6
Views: 453
Reputation: 213223
When I executed your code, I got the outputs in order. In fact got the same output for both the code. It seems like the Collector
returned from Collectors.toList
is already ordered, as being depicted by following code:
Collector collector = Collectors.toList();
System.out.print(collector.characteristics());
it prints:
[IDENTITY_FINISH]
Since there is no UNORDERED
characteristics set for the collector, it will process the elements in order only, and which is what the behaviour I'm seeing.
In fact this is clearly mentioned in the docs of Collectors.toList()
:
Returns:
aCollector
which collects all the input elements into aList
, in encounter order
Upvotes: 4