Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

collect a synchronized arraylist from streams in java 8

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.

like image 767
Manu Joy Avatar asked Jun 15 '15 08:06

Manu Joy


People also ask

How do you collect a Stream from an ArrayList?

All you need to do is first get the stream from List by calling stream() method, then call the filter() method to create a new Stream of filtered values and finally call the Collectors. toCollection(ArrayList::new) to collect those elements into an ArrayList.

How do I get the Synchronised version of the ArrayList object?

In order to get a synchronized list from an ArrayList, we use the synchronizedList(List <T>) method in Java. The Collections. synchronizedList(List <T>) method accepts the ArrayList as an argument and returns a thread safe list.

How can we create a synchronized collection from given collection?

We can use Collections. synchronizedList(List<T>) method to synchronize collections in java. The synchronizedList(List<T>) method is used to return a synchronized (thread-safe) list backed by the specified list.


2 Answers

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.

like image 64
assylias Avatar answered Oct 01 '22 06:10

assylias


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))
like image 41
Brian Goetz Avatar answered Oct 01 '22 07:10

Brian Goetz