Java中Lambda分组聚合靠Stream.collect()配合Collectors.groupingBy()及下游收集器,一行代码实现分组计数、求和、平均、最值、多级分组、BigDecimal运算及多指标统计。

Java 中用 Lambda 表达式做分组聚合统计,核心靠 Stream.collect() 配合 Collectors.groupingBy() 和各类下游收集器(downstream collector),无需手写循环,一行代码就能完成分组+计算。
按单字段分组并计数
最常用场景:统计每个分类有多少条数据。
- 用
Collectors.groupingBy(键提取函数, Collectors.counting()) - 例如按部门统计人数:
Map<String, Long> countByDept = list.stream().collect(Collectors.groupingBy(Person::getDepartment, Collectors.counting())); - 返回的是
Map<String, Long>,键是部门名,值是人数
分组后对数值字段求和、平均、最值
不只是数个数,还能算总和、均值、最大最小值等。
- 求和:
Collectors.summingInt(Person::getAge)→ 返回Map<String, Integer> - 求平均:
Collectors.averagingDouble(Person::getSalary)→ 返回Map<String, Double> - 取最大年龄的人:
Collectors.maxBy(Comparator.comparing(Person::getAge))→ 返回Map<String, Optional<Person>>,注意要判空
嵌套多级分组
比如先按城市分,再按年龄段分,形成树状结构。
立即学习“Java免费学习笔记(深入)”;
- 写法:
Collectors.groupingBy(Person::getCity, Collectors.groupingBy(p -> p.getAge() < 30 ? "青年" : "中年")) - 结果类型是
Map<String, Map<String, List<Person>>> - 如果还想在第二层加统计(如每城每年龄段人数),就把内层换成
Collectors.groupingBy(..., Collectors.counting())
自定义聚合逻辑(如 BigDecimal 求和)
内置收集器不支持 BigDecimal 直接 sum/avg,需用 reducing。
- BigDecimal 求和:
Collectors.reducing(BigDecimal.ZERO, Person::getSalary, BigDecimal::add) - 配合 groupingBy 使用:
Map<String, BigDecimal> sumByDept = list.stream().collect(Collectors.groupingBy(Person::getDepartment, reducing(...))); - 若想同时获取多个指标(如总和+平均+数量),可用
Collectors.summarizingInt(),它返回IntSummaryStatistics对象,含 count、sum、min、max、average


















