解密流减少功能

alw*_*ous 6 java java-stream

为什么都c1c2不被视为两个字符串,而是一个String和一个Integer

Arrays.asList("duck","chicken","flamingo","pelican")
            .stream()
            .reduce(0,
                    (c1, c2) -> c1.length() + c2.length(),
                    (s1, s2) -> s1 + s2);
Run Code Online (Sandbox Code Playgroud)

Ous*_* D. 4

该方法有三种reduce变体,其签名和返回类型有所不同。如果您查看reduce具有此签名的重载:

reduce(U identity, BiFunction<U,? super T,U> accumulator, BinaryOperator<U> combiner)
Run Code Online (Sandbox Code Playgroud)

从方法签名中可以看出,此重载reduce有 3 个参数:identity、accumulator 和combiner。身份值是您传递给reduceie ( 0) 的初始值,然后我们有累加器,它基本上将附加元素合并到结果中,最后,组合器的工作是将提供的两个值组合起来。

所以你问:

为什么 c1 和 c2 不被视为两个字符串,而是一个字符串和一个整数?

第一个参数在您的情况下是BiFunction这样,因此,用于标识值的类型必须与第一个参数的类型以及累加器函数()的返回类型相同。UIntegerBiFunction

除此之外,您需要更改此设置:

(c1, c2) -> c1.length() + c2.length()
Run Code Online (Sandbox Code Playgroud)

对此:

 (c1, c2) -> c1 + c2.length()
Run Code Online (Sandbox Code Playgroud)

需要注意的是,combiner函数 (s1, s2) -> s1 + s2根本不会被调用。原因是这个特定的重载被设计为与 一起使用parallelStream,因此为了使组合器工作,流必须是并行的。否则,只会调用累加器函数。

另一方面,您的完整代码可以简化为:

int result = Stream.of("duck","chicken","flamingo","pelican")
                   .reduce(0,
                   (c1, c2) -> c1 + c2.length(),
                   (s1, s2) -> s1 + s2);
Run Code Online (Sandbox Code Playgroud)

如果您想避免装箱/拆箱的开销,甚至更好reduce

int result = Stream.of("duck", "chicken", "flamingo", "pelican")
                   .mapToInt(String::length)
                   .sum();
Run Code Online (Sandbox Code Playgroud)