java是。收集保证在并行流上订购?
假设我有一个字符串列表List<String> toProcess
。结果必须与原始行的顺序一致。
我想利用新的并行流
以下代码是否保证结果的顺序与原始列表中的顺序相同
// ["a", "b", "c"]
List<String> toProcess;
// should be ["a", "b", "c"]
List<String> results = toProcess.parallelStream()
.map(s -> s)
.collect(Collectors.toList());
# 1 楼答案
TL;DR
是的,订单是有保证的
小溪。collect()API文档
首先要看看是什么决定了减量是否同时进行^{} 的描述如下:
满足第一个条件:流是平行的。第二个和第三个呢:
Collector
是并发的、无序的吗收藏家。toList()API文档
^{} 的文件内容如下:
在encounter order中工作的操作按元素的原始顺序对其进行操作。这压倒了平行性
实现代码
检查
Collectors.java
的执行情况确认toList()
不包括CONCURRENT
或UNORDERED
特征注意收集器是如何拥有
CH_ID
特征集的,它只有一个IDENTITY_FINISH
特征CONCURRENT
和UNORDERED
不存在,因此还原不能同时进行非并发缩减意味着,如果流是并行的,则收集可以并行进行,但它将被拆分为多个线程限制的中间结果,然后将这些结果合并。这确保了组合结果的顺序
另请参见:Why parallel stream get collected sequentially in Java 8
# 2 楼答案
你一定会把元素按顺序排列好
从documentation of ^{}
参见java.util.streams summary了解关于“遭遇顺序”一词的更多信息
此外,^{} 文档要求
List
的所有实现生成ORDERED
的拆分器:奇怪的是,虽然
List
接口需要iterator()
以“正确的顺序”生成元素,但是spliterator()
只需要按顺序排列,而不需要按照列表的自然顺序排列因此,为了回答您的问题,
toList
生成的列表保证包含的元素与源列表的拆分器对元素的排序完全相同。流是并行的还是顺序的并不重要