Java中如何使用Stream获取Map中分组列表的元素计数
解决方案
你可以直接通过Collectors.groupingBy的第二个参数指定下游收集器实现分组计数,无需分两步操作,也可以基于你已经得到的分组结果二次处理统计数量。
方式1:一步生成长度对应计数的Map(推荐)
直接在分组时指定Collectors.counting()作为下游收集器,直接得到每个长度对应的元素数量:
import java.util.Map; import java.util.stream.Collectors; import java.util.stream.Stream; public class GroupCountTest { public static void main(String[] args) { Map<Integer, Long> lengthCountMap = Stream.of("Brad", "Jack", "Leonardo", "Alexander", "Juliet", "William", "Audrey") .collect(Collectors.groupingBy( String::length, // 按字符串长度分组的规则不变 Collectors.counting() // 统计每个分组的元素个数 )); // 遍历输出结果 lengthCountMap.forEach((length, count) -> System.out.printf("长度%d:%d个%n", length, count)); } }
输出结果为:
长度4:2个 长度6:2个 长度7:1个 长度8:1个 长度9:1个
如果需要计数结果为Integer类型而非Long,可以用Collectors.collectingAndThen做类型转换:
Map<Integer, Integer> lengthCountMap = Stream.of("Brad", "Jack", "Leonardo", "Alexander", "Juliet", "William", "Audrey") .collect(Collectors.groupingBy( String::length, Collectors.collectingAndThen(Collectors.counting(), Long::intValue) ));
方式2:基于已有分组结果统计
如果你确实需要先拿到分组后的字符串列表做其他业务处理,再单独统计数量,可以直接对分组Map的entrySet转流处理:
// 你原有生成分组Map的逻辑 Map<Integer, List<String>> groupMap = Stream.of("Brad", "Jack", "Leonardo", "Alexander", "Juliet", "William", "Audrey") .collect(Collectors.groupingBy(String::length)); // 统计每个分组的元素数 Map<Integer, Integer> countMap = groupMap.entrySet() .stream() .collect(Collectors.toMap( Map.Entry::getKey, entry -> entry.getValue().size() )); countMap.forEach(System.out::println);
你原有代码外层套的Stream.of(...)是冗余逻辑,groupingBy已经返回了完整的Map对象,把整个Map作为元素塞进Stream里只能打印完整的Map结构,无法单独处理每个分组的计数。
内容的提问来源于stack exchange,提问作者Pouria
相关产品推荐
相关产品推荐

