小编典典

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

all

我无法完全理解combinerStreamsreduce方法中的作用。

例如,以下代码无法编译:

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 相加。

任何人都可以阐明这一点吗?


阅读 119

收藏
2022-07-07

共1个答案

小编典典

您尝试使用的两个和三个参数版本reduce不接受相同类型的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)。

另请注意,此版本的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 就可以了。

实现您想要的另一种方法:

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();
2022-07-07