我无法完全理解combinerStreamsreduce方法中的作用。
combiner
reduce
例如,以下代码无法编译:
int length = asList("str1", "str2").stream() .reduce(0, (accumulatedInt, str) -> accumulatedInt + str.length());
编译错误说:( 参数不匹配;int 无法转换为 java.lang.String)
但这段代码确实编译:
int length = asList("str1", "str2").stream() .reduce(0, (accumulatedInt, str ) -> accumulatedInt + str.length(), (accumulatedInt, accumulatedInt2) -> accumulatedInt + accumulatedInt2);
我知道组合器方法用于并行流 - 所以在我的示例中,它将两个中间累积整数相加。
但是我不明白为什么第一个示例在没有组合器的情况下无法编译,或者组合器如何解决字符串到 int 的转换,因为它只是将两个 int 相加。
任何人都可以阐明这一点吗?
您尝试使用的两个和三个参数版本reduce不接受相同类型的accumulator.
accumulator
这两个参数reduce定义为:
T reduce(T identity, BinaryOperator<T> accumulator)
在您的情况下,T 是字符串,因此BinaryOperator<T>应该接受两个字符串参数并返回一个字符串。但是您将一个 int 和一个 String 传递给它,这会导致您得到 - 的编译错误argument mismatch; int cannot be converted to java.lang.String。实际上,我认为在这里传递 0 作为标识值也是错误的,因为需要一个字符串 (T)。
BinaryOperator<T>
argument mismatch; int cannot be converted to java.lang.String
另请注意,此版本的reduce 处理Ts 流并返回T,因此您不能使用它将String 流减少为int。
三个参数reduce定义为:
<U> U reduce(U identity, BiFunction<U,? super T,U> accumulator, BinaryOperator<U> combiner)
在您的情况下,U 是整数,T 是字符串,因此此方法会将字符串流减少为整数。
对于BiFunction<U,? super T,U>累加器,您可以传递两种不同类型的参数(U 和 ? super T),在您的情况下是整数和字符串。此外,身份值 U 在您的情况下接受 Integer ,因此将其传递 0 就可以了。
BiFunction<U,? super T,U>
实现您想要的另一种方法:
int length = asList("str1", "str2").stream().mapToInt (s -> s.length()) .reduce(0, (accumulatedInt, len) -> accumulatedInt + len);
这里流的类型与 的返回类型匹配reduce,因此您可以使用 的两个参数版本reduce。
当然,您根本不必使用reduce:
int length = asList("str1", "str2").stream().mapToInt (s -> s.length()) .sum();