java中stream().filter()配合lambda可一行实现元素筛选,比for循环更简洁易读;需注意空值处理、纯函数原则、避免副作用,并支持链式操作与其他stream方法协作。

Java 中用 stream().filter() 配合 Lambda 表达式,能直接把“找哪些元素”这件事写成一行,比传统 for 循环加 if 判断更聚焦、更易读。
基础过滤:一行写清筛选条件
调用 stream() 把集合转为流,filter() 接收一个 Lambda,返回满足条件的新集合(原集合不变)。
- 语法简洁:如
list.stream().filter(s -> s.length() > 3).collect(Collectors.toList()),编译器自动推断参数类型,不用写String s - 必须确保集合非 null,否则触发
NullPointerException;可提前用Objects.requireNonNull(list)或封装在 Optional 中 - 常用结尾是
.collect(Collectors.toList())或 Java 16+ 的.toList(),注意结果是新 List,不是原集合的视图
复杂条件:拆出来,别堆在 filter 里
当判断逻辑变长或需复用,硬塞 Lambda 会降低可读性,应提取为独立单元。
- 封装成静态方法:例如
public static boolean isLongName(String s) { return s != null && s.length() > 5; },再写.filter(MyUtils::isLongName) - 定义 Predicate 常量:如
private static final Predicate<string> NON_BLANK = s -> s != null && !s.trim().isEmpty();</string>,复用时直接.filter(NON_BLANK) - 组合多个条件:用
and()、or()、negate(),比如NON_BLANK.and(s -> s.startsWith("A"))
安全与纯净:避开常见坑
filter 的 Lambda 应该是纯函数——只看输入、不改外部、不抛受检异常、不依赖状态。
- 空值优先处理:链首加
.filter(Objects::nonNull),或在条件里内联判空,避免 NPE - 禁止副作用:不要在 filter 里调
System.out.println()、改对象字段、写文件;调试可用peek(),但上线前删掉 - 不抛受检异常:如需 IO 或解析,把异常包装成
RuntimeException,或用工具方法封装异常处理逻辑
链式协作:过滤只是流水线一环
filter 天然适合和其他 Stream 操作串联,形成清晰的数据流意图。
- 先筛后转:如
.filter(Objects::nonNull).map(String::toUpperCase).collect() - 筛完取一个:用
.findFirst()或.findAny()替代手动 break 循环 - 配合去重:结合自定义
distinctByKey(Person::getName)实现按字段去重,避免嵌套循环
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











