【问题标题】:Counting number of names using Lambda Expression使用 Lambda 表达式计算名称的数量
【发布时间】:2016-07-21 23:54:07
【问题描述】:

如果我想计算名册中具有特定姓名的人数:
我应该得到类似[Bob:2, Joe:1, Mary:1, Kane: 1]

的输出
List<Person> names = Arrays.toList(Bob, Joe, Bob, Mary, Kane);

Map<String, List<int>> = names.stream().collect(
       Collectors.groupingBy(
            Person::getName,
            Collectors.reducing(
                0,
                //Is there a way here I can get the count of the names from the grouping by above this?
                Integer::sum
            )
       )
)

【问题讨论】:

  • Collectors.groupingBy(Person::getName, Collectors.counting()).
  • Collectors.summingInt(e-&gt;1) 可以胜任,但Collectors.counting() 更好。
  • 评论不是为了回答?

标签: java lambda reduce


【解决方案1】:

给定输入:

List<Person> names = Arrays.asList(Bob, Joe, Bob, Mary, Kane);

你可以使用这个 lambda 表达式:

 Map<String, Integer> counts = names.stream().collect(
    Collectors.toMap(Person::getName, counter -> 1, Integer::sum, LinkedHashMap::new)
);

产生:

{Bob=2, Joe=1, Mary=1, Kane=1}

考虑到 Federico 的建议,答案可以更新为:

Map<String, Long> counts = names.stream().collect(
    Collectors.groupingBy(Person::getName, LinkedHashMap::new, Collectors.counting()));

【讨论】:

  • 名字的顺序现在不同了.. 不过 OP 可能没问题
  • 没有理由使用toConcurrentMap,你可以使用toMap,即使你使用了并行流。
  • @Jayan:如果订单很重要,您可以使用Collectors.toMap(Person::getName, counter -&gt; 1, Integer::sum, LinkedHashMap::new)
  • 大家好,很抱歉回复晚了!但我有一个关于你上面的方法的快速问题。当你做Map&lt;String, Long&gt; counts = names.stream().collect( Collectors.groupingBy(Person::getName, LinkedHashMap::new, Collectors.counting())); 那么这个列表会首先按相同的名字分组吗?因此它将按所有名称分组,因此您将拥有[bob, bob, joe, mary, kane],然后它将创建 ONE 新的 LinkedHashMap,最后它将计算由groupingBy 创建的列表中每个项目的出现次数并将其放入 LinkedHashMap 中?
  • 差不多。该语句首先创建一个新的 LinkedHashMap,它自然地对键进行排序。然后按照您的描述按名称分组,因此名称是地图的关键。每个键的值是 Collectors.counting() 的结果,如果这是人名的第一次出现,它将把 1 作为映射中键的值,或者如果人已经存在,它将增加计数作为地图中的一个键。
猜你喜欢
  • 2021-04-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多