从 java 8 中的并行流收集

我想获取输入并对其应用并行流,然后我希望输出为列表。输入可以是我们可以应用流的任何列表或任何集合。

我在这里担心的是,如果我们想要输出作为映射它们,我们有一个来自java的选项,就像

list.parallelStream().collect(Collectors.toConcurrentMap(args))

但是,我看不到以线程安全的方式从并行流中收集的选项,以提供列表作为输出。我看到还有一个选项可以使用

list.parallelStream().collect(Collectors.toCollection(<Concurrent Implementation>))

通过这种方式,我们可以在收集方法中提供各种并发实现。但我认为只有CopyOnWriteArrayList List实现存在于java.util.concurrent中。我们可以在这里使用各种队列实现,但这些不会像列表一样。我在这里的意思是,我们可以解决方法来获取列表。

如果我想要输出为列表,您能指导我最好的方法是什么吗?

注意:我找不到与此相关的任何其他帖子,任何参考都会有所帮助。


答案 1

用于接收所收集数据的对象不需要是并发的。你可以给它一个简单的.CollectionArrayList

这是因为来自并行流的值的集合实际上并没有收集到单个对象中。每个线程将收集自己的数据,然后所有子结果将合并到单个最终对象中。CollectionCollection

这在 Collector javadoc 中有很好的记录,并且是您提供给 collect() 方法的参数:Collector

<R,A> R collect(Collector<? super T,A,R> collector)

答案 2

But there is no option that I can see to collect from parallel stream in thread safe way to provide list as output.这是完全错误的。

流的重点是,您可以使用非线程安全集合来实现完全有效的线程安全结果。这是因为流的实现方式(这是流设计的关键部分)。您可以看到,a 定义了一个方法,该方法在每个步骤中将创建一个新实例。这些实例将在它们之间合并。Collectorsupplier

所以这是完全线程安全的:

 Stream.of(1,2,3,4).parallel()
          .collect(Collectors.toList());

由于此流中有 4 个元素,因此将有 4 个创建的实例在末尾合并到单个结果中(假设至少有 4 个 CPU 内核)ArrayList

另一方面,像生成单个结果容器这样的方法,所有线程都会将其结果放入其中。toConcurrent


推荐