Java中用Lambda过滤集合数据需借助Stream的filter()方法,以简洁匿名函数替代传统循环判断;须前置判空防NPE;复杂条件应封装为Predicate复用;filter须置于map前且保持无副作用。

Java 中用 Lambda 表达式过滤集合数据,核心是借助 Stream 的 filter() 方法,把判断逻辑写成简洁、可读的匿名函数,替代传统 for 循环加 if 判断。
基础写法:一行完成筛选
从集合转流 → 用 Lambda 定义条件 → 收集结果:
-
list.stream().filter(x -> x.getAge() > 18).collect(Collectors.toList())—— 筛成年人 -
names.stream().filter(s -> s != null && s.length() > 2).collect(Collectors.toList())—— 排除空值并保留长度超 2 的字符串
空安全必须前置处理
元素为 null 是常见隐患,不能依赖 filter 内部判空来兜底,否则调用方法时直接抛 NullPointerException:
在调试 Java 后端 API 故障时使用此技能,尤其适用于以下任务:分析日志、跨 Controller、Service 和 Mapper 层追踪请求、定位异常根因、检查 SQL 执行或参数流转,以及生成简洁的诊断结论与修复方案。
- 开头加
.filter(Objects::nonNull),确保后续操作对象非空 - 若字段本身可能为空(如
user.getAddress().getCity()),应在 Lambda 中显式判空:u -> u.getAddress() != null && "BJ".equals(u.getAddress().getCity())
复杂条件建议封装成 Predicate
当逻辑变长或需复用,硬写在 filter 里会降低可读性:
立即学习“Java免费学习笔记(深入)”;
- 定义静态方法:
public static boolean isHighScore(User u) { return u.getScore() >= 90; },再用.filter(MyUtils::isHighScore) - 声明常量谓词:
private static final Predicate<user> ACTIVE_ADULT = u -> u.isActive() && u.getAge() >= 18;</user>,复用时直接.filter(ACTIVE_ADULT) - 组合多个条件:
ACTIVE_ADULT.and(hasValidEmail)或NOT_EMPTY.negate()
注意链式顺序和副作用
filter 在整个 Stream 流水线中位置很关键:
-
filter要放在map前面,避免对 null 元素调用方法 - 不要在 filter 的 Lambda 里修改外部变量、打印日志、发 HTTP 请求——它应是纯函数
- 需要调试时可用
peek(System.out::println),但生产环境慎用

















