从java 8中的流中收集同步的arraylist

Man*_*Joy 4 java synchronization arraylist thread-safety java-8

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

上面的代码将创建一个不是线程安全的ArrayList.那么如何才能使其线程安全.

ass*_*ias 5

如果您想要同步集合,您只需更改集合器以提供所需的实现,例如:

.collect(Collectors.toCollection(() -> Collections.synchronizedList(new ArrayList<> ()));
Run Code Online (Sandbox Code Playgroud)

或者如果您更喜欢并发集合:

.collect(Collectors.toCollection(CopyOnWriteArrayList::new));
Run Code Online (Sandbox Code Playgroud)

在后一种情况下,使用复制构造函数来避免底层数组的不必要副本可能更有效.


Bri*_*etz 5

稍微好一点的方法是将包装移动到收集器中:

map.entrySet().stream()
   .map(Map.Entry::getValue)
   .flatMap(x -> x.stream())
   .collect(collectingAndThen(toList(), 
                              Collections::synchronizedList))
Run Code Online (Sandbox Code Playgroud)