[英]Collectors.summingInt() and Collectors.joining()
我有一个Cat
class,它有String name
和int tailLength
字段以及String getName()
和int getTailLength()
方法。 Cat
实例被放置在List<Cat> cats
中。 我的问题:
为什么这可以正常工作:
int tailsEndToEnd = cats.stream().collect(Collectors.summingInt(Cat::getTailLength); //(1)
这不会:
String allNames = cats.stream().collect(Collectors.joining(Cat::getName); //(2)
我知道我可以像这样收集猫的名字:
cats.stream().collect(Collectors.mapping(Cat::getName, joining(", ")); //(3),
只是好奇为什么(2)不起作用,看到它完全类似于(1),不管 output 看起来如何(没有逗号等)。
谢谢
所有Collector.joining
变体都返回一个Collector<CharSequence, ?, String>
,这意味着它们只能对Stream<CharSequence>
进行操作。
当您使用Collectors.mapping(Cat::getName,joining(", "));
, mapping
将您的Stream<Cat>
转换为Stream<CharSequence>, which allows that
Stream to be processed by
join()` 处理。
您不能使用 Join 直接处理Stream<Cat>
,因为它没有接受映射joining
以将您的Cat
转换为String
的变体。 joining
的所有 arguments 都是CharSequence
,用作分隔符、前缀或后缀。
这与summingInt
不同,后者接受ToIntFunction<? super T>
ToIntFunction<? super T>
映射器 function 到 map 将Stream
的元素转换为int
。
Eran 的回答基本上总结了它,我只是想在您的具体情况下补充一点,实现您想要的更惯用(并且绝对更具可读性)的方式是:
String catNames = cats.stream().map(Cat::getName).collect(Collectors.joining());
这样每个操作都可以独立检查,因此易于阅读和理解:
而在您的第三个示例中,您正在执行collect
内部的两个操作,这不太自然。
我没有看到解决的问题是接受一个参数的 Collectors.joining 方法只接受一个 CharSequence 作为参数:
公共 static ... 加入(字符序列分隔符)
(这里重要的不是返回类型,而是方法参数定义。)
Cat::getName
不是 CharSequence,它是一个方法引用(可以解释为一个函数)。 它永远不会是该方法的合适论据。
正如其他人所说,您需要先将 map 转换为字符串,然后调用 Collections.joining,使用零 arguments 或使用单个分隔符参数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.