为什么c1
和c2
都不会被视为两个字符串,而是一个String
和一个Integer
?
Arrays.asList("duck","chicken","flamingo","pelican")
.stream()
.reduce(0,
(c1, c2) -> c1.length() + c2.length(),
(s1, s2) -> s1 + s2);
答案 0 :(得分:4)
reduce
方法有三个变体,它们的签名和返回类型不同。如果您查看具有此签名的reduce
的重载:
reduce(U identity, BiFunction<U,? super T,U> accumulator, BinaryOperator<U> combiner)
从方法签名中可以看出,reduce
的重载有3个参数 identity ,累加器和组合器。身份值是您传递给reduce
的初始值,即(0
),然后我们有累加器,它基本上将一个额外的元素合并到一个结果中,最后,组合器 whos的职责是组合提供的两个值。
所以你问:
为什么c1和c2都不被视为两个字符串而是一个字符串 字符串和一个整数?
BiFunction
的第一个参数是U
,在您的情况下是Integer
因此,用于身份值的类型必须相同第一个参数的类型以及累加器函数的返回类型(BiFunction
)。
除此之外,你需要改变这个:
(c1, c2) -> c1.length() + c2.length()
到此:
(c1, c2) -> c1 + c2.length()
重要的是要注意,根本不会调用组合器功能 (s1, s2) -> s1 + s2
。原因是此特定重载旨在与parallelStream
一起使用,因此为了使组合器工作,流必须并行。否则,只会调用累加器函数。
作为一方,您的完整代码可以简化为:
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();
答案 1 :(得分:1)
我相信您正在尝试执行以下操作:
Arrays.asList("duck", "chicken", "flamingo", "pelican")
.stream()
.map(c -> c.length())
.reduce((c1, c2) -> c1 + c2);
首先,将每个String映射到它的长度,基本上进行以下转换:
("duck", "chicken", "flamingo", "pelican") -> (4, 7, 8, 7)
然后,通过添加值来减少该结果。