从 java 8 中的并行流中收集

collecting from parallel stream in java 8

我想接受输入并在其上应用并行流,然后我想输出为列表。输入可以是我们可以应用流的任何列表或任何集合。

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

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

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

的选项

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

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

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

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

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

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

这在 Collector javadoc, and the Collector is the parameter you're giving to the collect() 方法中都有详细记录:

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

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

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

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

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

由于此流中有 4 个元素,因此将创建 4 个 ArrayList 实例,它们将在最后合并为一个结果(假设至少有 4 个 CPU 核心)

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