java - 为什么在java 8中转换类型的reduce方法需要组合器

标签 java java-8 java-stream

我无法完全理解 combiner 的作用在 Streams 中实现 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);
我知道在并行流中使用了组合器方法 - 所以在我的例子中,它将两个中间累积整数加在一起。
但是我不明白为什么第一个示例在没有组合器的情况下无法编译,或者组合器如何解决 string 到 int 的转换,因为它只是将两个 int 相加。
任何人都可以阐明这一点吗?

最佳答案

reduce 的两个和三个参数版本您尝试使用的 accumulator 不接受相同的类型.

两种说法reducedefined as :

T reduce(T identity,
         BinaryOperator<T> accumulator)

在你的情况下,T 是字符串,所以 BinaryOperator<T>应该接受两个字符串参数并返回一个字符串。但是你传递给它一个 int 和一个 String,这会导致你得到编译错误 - argument mismatch; int cannot be converted to java.lang.String .实际上,我认为在这里将 0 作为标识值传递也是错误的,因为需要字符串 (T)。

另请注意,此版本的reduce 处理Ts 流并返回T,因此您不能使用它来将String 流减少为int。

三论reducedefined as :
<U> U reduce(U identity,
             BiFunction<U,? super T,U> accumulator,
             BinaryOperator<U> combiner)

在您的情况下,U 是整数,T 是字符串,因此此方法会将字符串流减少为整数。

对于 BiFunction<U,? super T,U> accumulator 你可以传递两种不同类型的参数(U 和 ? super T),在你的情况下是整数和字符串。此外,在您的情况下,标识值 U 接受一个 Integer,因此将它传递给 0 就可以了。

实现您想要的另一种方法:
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();

关于java - 为什么在java 8中转换类型的reduce方法需要组合器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24308146/

相关文章:

Java Web 应用程序监控和容错

java - 如何使用 JFileChooser 将文件保存到选定的目录

java - 我在哪里可以找到 Netbeans 中的 Xlint 选项?

java - Eclipse "open implementation"它位于父类(super class)中

scala - 这是 java lambda 在设计中的限制吗

Java Applet init 非常慢 - java 1.8。 u60

java - 无法使用 javapackager 从 .JAR 构建 DMG

Java:对两个或多个时间序列求和

java - 使用Streams为列表的每个元素调用方法

使用 Stream 的 Java 8 模式谓词 - 如何推断变量?