filter没生效是因为它不修改原List且需终端操作;返回值必须为boolean;null需提前过滤;性能上filter应前置;并行流不保证顺序。

filter() 为什么没生效?检查返回值是不是布尔类型
Java 的 filter() 不会原地修改 List,它返回的是新 Stream,必须链式调用 collect() 才能得到结果。常见错误是只写 list.stream().filter(...) 就结束,结果什么也没变。
- 必须接
collect(Collectors.toList())或其他终端操作,否则整个 Stream 被丢弃 - Lambda 表达式里写的条件必须明确返回
boolean:比如x -> x > 0合法,x -> System.out.println(x)编译不通过 - 如果用方法引用,确保被引用方法签名是
Object -> boolean,例如String::isEmpty可以,Object::toString不行
空值(null)导致 NullPointerException 怎么办
Stream 中若存在 null 元素,而 filter 条件里直接调用方法(如 s -> s.length() > 5),运行时抛 NullPointerException。这不是 filter 的 bug,是 null 安全没做。
- 提前过滤掉 null:
filter(Objects::nonNull) - 在条件里防御性判断:
filter(s -> s != null && s.length() > 5) - 如果业务允许 null 表示“无效”,建议统一前置清理,避免每个 filter 都重复判空
性能敏感场景下,filter 放前面还是后面
Stream 操作是惰性求值,但 filter 的位置会影响实际遍历元素数量。尤其当后续还有 map()、sorted() 等开销大的操作时,顺序很关键。
- 优先把
filter()放在map()前面:避免对大量无用元素做转换 - 如果
sorted()在 filter 后,且数据量大,考虑先 filter 再 sort;否则 sort 会处理全部元素,浪费 CPU 和内存 - 注意
distinct()和limit()的位置:filter + limit 组合常用于分页前筛选,比先 limit 再 filter 更准
想保留原始 List 顺序,但 filter 后结果不对?确认没混用并行流
stream() 是顺序流,parallelStream() 是并行流。后者不保证遍历顺序,filter + collect 后 List 顺序可能乱 —— 即使你没显式排序,也不等于“和原 list 顺序一致”。
立即学习“Java免费学习笔记(深入)”;
- 默认用
list.stream().filter(...).collect(...),顺序严格保持 - 如果用了
parallelStream(),又依赖顺序,要么换回stream(),要么加forEachOrdered()(但会损失并行收益) - 并行流 + filter 对 CPU 密集型小对象过滤有加速效果,但对简单字符串判断,往往不如顺序流快(线程调度开销压倒收益)










