最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
Java Stream API分组过滤:GroupingBy与Filter配合
时间:2026-06-20 08:28:55 编辑:袖梨 来源:一聚教程网
groupingBy本身不过滤,过滤需用filter()(分组前全局过滤)或filtering(分组后各组独立过滤);错误地在mapping中条件返回null会引发异常。
Java Stream API 中,groupingBy 本身不负责过滤,它只做分组;真正执行过滤逻辑的,是配合使用的下游 Collector(如 filtering)或前置的 filter() 操作。关键区别在于:前者在每个分组内部过滤,后者在分组前全局过滤——选错位置会导致结果偏差。
分组前过滤:用 stream.filter()
适用于“先筛再分”的场景,比如剔除无效数据后再按属性归类。
- 操作时机:在
.collect(Collectors.groupingBy(...))之前调用 - 影响范围:整个流,所有后续分组操作都基于已过滤的数据
- 示例:只统计状态为
ACTIVE的用户,并按部门分组
users.stream()
.filter(u -> "ACTIVE".equals(u.getStatus()))
.collect(Collectors.groupingBy(User::getDepartment));
分组后过滤:用 Collectors.filtering()
适用于“分组后按条件保留部分元素”,比如每个部门只保留薪资高于阈值的员工。
立即学习“Java免费学习笔记(深入)”;
- 操作时机:作为
groupingBy的下游 Collector 使用 - 影响范围:每个分组独立过滤,不同组可应用不同规则
- 要求:Java 9+(
Collectors.filtering是 Java 9 引入)
users.stream()
.collect(Collectors.groupingBy(
User::getDepartment,
Collectors.filtering(u -> u.getSalary() > 15000, Collectors.toList())
));
避免常见错误:别在 mapping 里写 if 添加元素
有人试图在 mapping 中用条件判断来“选择性添加”,例如:
// ❌ 错误:有副作用,且逻辑混乱
Collectors.mapping(u -> {
if (u.getAge() > 18) return u;
else return null; // null 会引发异常
}, Collectors.toList())
这不仅破坏函数式风格,还可能抛出 NullPointerException。正确做法是把过滤逻辑交给 filtering 或前置 filter。
进阶技巧:组合 filtering + mapping 精简结果
如果分组后只需提取某个字段(如 ID),而不是整个对象,可链式组合:
- 先过滤符合条件的对象
- 再映射为所需字段(如
getId()) - 最后收集为 List
orders.stream()
.collect(Collectors.groupingBy(
Order::getStatus,
Collectors.filtering(o -> o.getAmount() > 1000,
Collectors.mapping(Order::getId, Collectors.toList())
)
));
相关文章
- 剪映 AI企业版收费说明:功能权限与免费版差异 06-20
- 赣服通怎么办理母女关系证明 赣服通申请开具亲属关系证明方法 06-20
- 2026年剪映AI插件功能与适用场景说明 06-20
- 即梦AI企业版与个人版差异:权限、费用与适用范围说明 06-20
- Linux Exploit揭秘:黑客攻击手段汇总 06-20
- Debian Syslog 实现日志加密的途径 06-20