简体   繁体   中英

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.

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.

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))

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)))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM