鉴于我有一个字符串列表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());
Run Code Online (Sandbox Code Playgroud)
Joh*_*ica 52
是的,订单是有保证的.
起点是看什么决定减少是否并发.Stream.collect()
的描述如下:
如果流是并行的,并且
Collector
是并发的,并且流是无序的或收集器是无序的,那么将执行并发减少(Collector
有关并发减少的详细信息,请参阅.)
满足第一个条件:流是并行的.第二个和第三个怎么样:Collector
并发和无序?
toList()
的文件是:
返回一个
Collector
将输入元素累积为new的元素List
.返回的类型,可变性,可序列性或线程安全性无法保证List
; 如果List
需要对返回的更多控制,请使用toCollection(Supplier)
.返回:
一个收集器,它按照遭遇顺序将所有输入元素收集到List 中
以遭遇顺序工作的操作按原始顺序对元素进行操作.这取代了并行性.
检查实施Collectors.java
确认toList()
并没有包含CONCURRENT
或UNORDERED
特征.
public static <T>
Collector<T, ?, List<T>> toList() {
return new CollectorImpl<>((Supplier<List<T>>) ArrayList::new, List::add,
(left, right) -> { left.addAll(right); return left; },
CH_ID);
}
// ...
static final Set<Collector.Characteristics> CH_ID
= Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.IDENTITY_FINISH));
Run Code Online (Sandbox Code Playgroud)
注意收集器如何具有CH_ID
特征集,该特征集仅具有单个IDENTITY_FINISH
特征.CONCURRENT
并且UNORDERED
不存在,因此减少不能同时进行.
非并发减少意味着,如果流是并行的,则集合可以并行进行,但是它将被分成几个线程限制的中间结果,然后将其组合.这确保了组合结果处于遭遇顺序.
另请参阅: 为什么在Java 8中按顺序收集并行流
您可以保证获得遇到订单的元素.
来自以下文件toList
:
返回:一个收集器,它按照遭遇顺序将所有输入元素收集到List 中
有关术语"遇到订单"的更多信息,请参阅java.util.streams摘要.
此外,List#spliterator
文档要求List
生成分裂器的所有实现是ORDERED
:
Spliterator报告Spliterator.SIZED和Spliterator.ORDERED.实施应记录其他特征值的报告.
奇怪的是,虽然List
界面需要iterator()
以"正确的顺序"生成元素,但只需要按顺序spliterator()
排序,但不需要特别要求遵循列表的自然顺序.
因此,为了回答你的问题,所产生的列表toList
保证包含与源列表的分裂器命令它们完全相同的元素.流是并行还是顺序无关紧要.
归档时间: |
|
查看次数: |
6330 次 |
最近记录: |