无法保证在合并之前已将累加器应用于容器。换句话说,要合并的列表可能为空。
IntStream.range(0, 10).parallel().boxed()
.filter(i -> i >= 3 && i < 7)
.collect(ArrayList::new, List::add, (l1,l2)->{
System.out.println(l1.size()+" + "+l2.size());
l1.addAll(l2);
});
0 + 0
0 + 0
0 + 0
1 + 1
0 + 2
0 + 2
1 + 1
2 + 0
2 + 2
当筛选器操作的结果还不知道时,工作负载拆分会在源列表中发生。每个块都以相同的方式处理,而不必重新检查是否有任何元素已到达累加器。
IntStream.range(0, 10).parallel().boxed()
.collect(Collectors.filtering(i -> i >= 3 && i < 7, Collectors.toList()));
这也是为什么收藏家
toList()
收集器)应准备好遇到空容器,因为过滤发生在容器外部
Stream
实施和评估
accept
调用复合收集器并不总是意味着
接受
呼叫下游收集器。
能够处理空集装箱的要求在
Collector
documentation
:
为了确保顺序执行和并行执行产生相等的结果,收集器函数必须满足
associativity
约束条件。
a
这是一系列累加器和组合器调用的结果,
一
必须等于
combiner.apply(a, supplier.get())
.