从 java 8 中的流中收集同步数组列表

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

以上代码将创建一个非线程安全的 ArrayList。那么如何使它线程安全。

您可以在创建后在其上添加同步代理

Collections.synchronizedList(map.entrySet()
                 .stream()
                     .map(Map.Entry::getValue)
                     .flatMap(x -> x.stream())
                     .collect(Collectors.toCollection(ArrayList::new)))

如果你想要一个同步的集合,你可以改变你的收集器来提供你想要的实现,例如:

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

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

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

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

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

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