首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Collectors.summingInt()和Collectors.joining()

Collectors.summingInt()和Collectors.joining()
EN

Stack Overflow用户
提问于 2022-01-09 14:30:59
回答 3查看 104关注 0票数 1

我有一个Cat类,它有String nameint 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),不管输出是什么样子(没有逗号,等等)。

谢谢

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2022-01-09 14:36:47

所有Collector.joining变体都返回一个Collector<CharSequence, ?, String>,这意味着它们只能在Stream<CharSequence>上操作。

当您使用Collectors.mapping(Cat::getName,joining(", "));时,mapping将您的Stream<Cat>转换为Stream<CharSequence>,这允许joining()处理该Stream

您不能使用Stream<Cat>直接处理joining,因为它没有接受映射函数将Cat转换为String的变体。joining的所有参数都是CharSequences,用作分隔符、前缀或后缀。

这与summingInt不同,后者接受ToIntFunction<? super T>映射函数将Stream的元素映射到int

票数 3
EN

Stack Overflow用户

发布于 2022-01-09 14:43:58

Eran的回答基本上概括了这一点,我只想补充一下,在你的具体情况下,一个更地道(当然更容易理解)的方式来实现你想要的是:

代码语言:javascript
复制
String catNames = cats.stream().map(Cat::getName).collect(Collectors.joining());

通过这种方式,每个操作都可以独立地进行检查,因此易于阅读和理解:

  1. 将猫的列表映射到它们的名字列表
  2. 将cat名称列表加入到单个字符串中

而在您的第三个示例中,您在collect中执行这两个操作,这不太容易阅读。

票数 3
EN

Stack Overflow用户

发布于 2022-01-10 13:06:12

我还没有看到的是,接受一个参数的Collectors.joining方法只接受一个CharSequence作为一个论点:

公共静态…连接(CharSequence分隔符)

(这里重要的不是返回类型,而是方法参数定义。)

Cat::getName不是一个CharSequence,它是一个方法引用(可以解释为一个函数)。对这种方法来说,这永远不是一个合适的论据。

正如其他人所说的,您需要首先映射到一个字符串,然后调用Collections.joining,要么使用零参数,要么使用单个分隔符参数。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70642237

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档