collect a synchronized arraylist from streams in java 8
Asked Answered
T

3

5
List<String> result = map.entrySet()
                 .stream()
                     .map(Map.Entry::getValue)
                     .flatMap(x -> x.stream())
                     .collect(Collectors.toCollection(ArrayList::new));

The above code will create a ArrayList which is not thread safe. So how can be make it thread safe.

Tripalmitin answered 15/6, 2015 at 8:46 Comment(3)
Why don't you just use map.values().stream()?Knute
Also, is your map thread safe at all?Knute
Please note that you need the thread-safe collection only if you want to perform structural modifications on it afterwards. If you want to use it as read-only, ArrayList will work fine. Also you don't need a thread-safe collection even if you want to run this stream operation in parallel.Audun
D
7

If you want a synchronized collection, you can just change your collector to provide the implementation you want, for example:

.collect(Collectors.toCollection(() -> Collections.synchronizedList(new ArrayList<> ()));

Or if you prefer a concurrent collection:

.collect(Collectors.toCollection(CopyOnWriteArrayList::new));

In the latter case, it may be more efficient to use the copy constructor to avoid unnecessary copies of the underlying array.

Directorial answered 15/6, 2015 at 8:48 Comment(0)
A
5

Slightly better is to move the wrapping into the Collector:

map.entrySet().stream()
   .map(Map.Entry::getValue)
   .flatMap(x -> x.stream())
   .collect(collectingAndThen(toList(), 
                              Collections::synchronizedList))
Agnew answered 15/6, 2015 at 12:5 Comment(0)
I
2

You can add a synchronized proxy over it after you create it

Collections.synchronizedList(map.entrySet()
                 .stream()
                     .map(Map.Entry::getValue)
                     .flatMap(x -> x.stream())
                     .collect(Collectors.toCollection(ArrayList::new)))
Intumescence answered 15/6, 2015 at 8:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.