I want to take an input and apply parallel stream on that, then I want output as list. Input could be any List or any collection on which we can apply streams.
My co
But there is no option that I can see to collect from parallel stream in thread safe way to provide list as output
. This is entirely wrong.
The whole point in streams is that you can use a non-thread safe Collection to achieve perfectly valid thread-safe results. This is because of how streams are implemented (and this was a key part of the design of streams). You could see that a Collector
defines a method supplier
that at each step will create a new instance. Those instances will be merged between them.
So this is perfectly thread safe:
Stream.of(1,2,3,4).parallel()
.collect(Collectors.toList());
Since there are 4 elements in this stream, there will be 4 instances of ArrayList
created that will be merged at the end to a single result (assuming at least 4 CPU cores)
On the other side methods like toConcurrent
generate a single result container and all threads will put their result into it.
The Collection
object used to receive the data being collected does not need to be concurrent. You can give it a simple ArrayList
.
That is because the collection of values from a parallel stream is not actually collected into a single Collection
object. Each thread will collect their own data, and then all sub-results will be merged into a single final Collection
object.
This is all well-documented in the Collector javadoc, and the Collector
is the parameter you're giving to the collect() method:
<R,A> R collect(Collector<? super T,A,R> collector)