我觉得从java.util.stream
包摘要Reduction operations款能回答这个问题。让我引用在这里最重要的部分:
在其更一般的形式,在类型<T>
产生<U>
类型的结果的元素减少操作需要三个参数:
<U> U reduce(U identity,
BiFunction<U, ? super T, U> accumulator,
BinaryOperator<U> combiner);
在这里,标识元素既是缩减的初始种子值,又是没有输入元素时的默认结果。累加器函数获取部分结果和下一个元素,并生成新的部分结果。组合器功能将两个部分结果组合以产生新的部分结果。 (组合器在并行减少中是必需的,其中输入被分区,为每个分区计算部分累积,然后将部分结果组合以产生最终结果。)更正式地,标识值必须是组合器功能。这意味着对于所有的u
,combiner.apply(identity, u)
等于u
。另外,组合器功能必须是关联的,并且必须与累加器功能兼容:对于所有的u
和t
,combiner.apply(u, accumulator.apply(identity, t))
必须是equals()
到accumulator.apply(u, t)
。
三参数形式是两个参数形式的泛化,将映射步骤合并到累加步骤中。使用更一般的形式,如下所示,我们可以重新浇铸求和的权重的简单的例子:
int sumOfWeights = widgets.stream()
.reduce(0,
(sum, b) -> sum + b.getWeight())
Integer::sum);
虽然明确的地图,减少形式的可读性,因此应通常是优选的。通过将映射和减少组合到一个函数中,可以优化大量工作的情况下提供了广义形式。
换言之,据我明白了,三个参数的形式在两种情况下是有用的:
- 当并行执行的事项。
- 当通过组合映射和累积步骤可以实现显着的性能优化时。否则,可以使用更简单和可读的显式映射缩减表单。
明确的形式在同一文档前面提到的:
int sumOfWeights = widgets.parallelStream()
.filter(b -> b.getColor() == RED)
.mapToInt(b -> b.getWeight())
.sum();
那确实功能。并行性上有趣的想法 - 将尝试... –
这似乎是它。插入“.parallel()”会导致返回1000000。 –
@Garth酷,迫不及待地尝试一下自己! –