有three的变化reduce https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#reduce-U-java.util.function.BiFunction-java.util.function.BinaryOperator-方法,其签名和返回类型有所不同。如果你看一下过载情况reduce https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#reduce-U-java.util.function.BiFunction-java.util.function.BinaryOperator-它有这个签名:
reduce(U identity, BiFunction<U,? super T,U> accumulator, BinaryOperator<U> combiner)
正如您从方法签名中看到的,此重载reduce https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#reduce-U-java.util.function.BiFunction-java.util.function.BinaryOperator-有 3 个参数identity、累加器和组合器。身份值是您传入的初始值reduce
i.e (0
),然后我们有了累加器,它基本上将一个附加元素合并到结果中,最后,combinerwho 的工作是将提供的两个值结合起来。
所以你问:
为什么 c1 和 c2 不被视为两个字符串而是一个
字符串和一个整数?
第一个参数BiFunction
is U
在你的情况下是Integer
因此,用于标识值的类型must与第一个参数的类型以及累加器函数的返回类型相同(BiFunction
).
除此之外,您需要更改此设置:
(c1, c2) -> c1.length() + c2.length()
to this:
(c1, c2) -> c1 + c2.length()
重要的是要注意组合器function (s1, s2) -> s1 + s2
根本不会被调用。原因是这个特定的重载被设计为与parallelStream
,所以为了让组合器工作,一个流must是平行的。否则,只会调用累加器函数。
另一方面,您的完整代码可以简化为:
int result = Stream.of("duck","chicken","flamingo","pelican")
.reduce(0,
(c1, c2) -> c1 + c2.length(),
(s1, s2) -> s1 + s2);
或者如果您想避免装箱/拆箱的开销,那就更好了reduce
:
int result = Stream.of("duck", "chicken", "flamingo", "pelican")
.mapToInt(String::length)
.sum();