我编写了以下代码示例来计算流中的总字符串长度:
/src/main/webapp/WEB-INF/jsp/welcome.jsp
我看到以下输出:
Integer reduce = Stream.of("AAA", "BBB", "CCC")
.reduce(0, (result, s) -> {
System.out.println("#accumulator# " + s);
return result + s.length();
}, (integer, integer2) -> {
System.out
.println("#combiner#" + "integer: " + integer + "integer2:" + integer2);
return integer + integer2;
});
System.out.println(reduce);
正如你所看到的,我得到了正确的结果,但组合器永远不会调用。
为什么呢?这是如何工作的?
请解释概念。
答案 0 :(得分:3)
Stream.reduce
中的组合器参数实际上仅在并行Stream的情况下被调用。这是因为当流并行执行时,Java会将流分区为多个子流。聚合操作迭代并并行处理这些子流,然后合并结果。
通过调用parallel()
更改您的代码以使用并行流,您将看到组合器被调用。
在此方法的Javadoc中,您可以看到等效代码中不存在combiner
:
这相当于:
U result = identity; for (T element : this stream) result = accumulator.apply(result, element) return result;
答案 1 :(得分:2)
TL; DR:为并行Streams 调用组合器。
当Spliterator
为split()
时,会在两个不同的Thread
处理时调用合并函数,并且需要合并结果。由于Stream
不是parallel
,因此不需要此功能。
顺便提一下,您的代码更好地写为:
final int total = Stream.of("AAA", "BBB", "CCC")
.mapToInt(String::length)
.sum();