filter筛选数据需传入返回boolean的谓词,推荐用方法引用(如User::isAdult)提升可读性与复用性;避免复杂lambda,多条件应拆分为多个filter;注意null安全,不可有副作用;常与map、sorted等链式组合使用。

用 filter 筛选数据,核心是传入一个返回 boolean 的谓词(Predicate),它会保留使该条件为 true 的元素。
写简洁可读的 lambda 表达式
避免在 filter 里写复杂逻辑。把判断逻辑抽成方法引用或独立方法,提升可读性和复用性。
- ✅ 推荐:用方法引用代替内联判断
// 好:清晰表达意图
List<User> adults = users.stream()
.filter(User::isAdult)
.collect(Collectors.toList());
// 对应的 User 类中
public boolean isAdult() {
return age >= 18;
}
- ⚠️ 避免:把多层判断塞进 lambda
// 不推荐:可读性差,难以测试和复用 .filter(u -> u != null && u.getAge() >= 18 && "CN".equals(u.getCountry()) && u.isActive())
组合多个 filter 提升可维护性
当筛选条件较多且语义独立时,拆成多个 filter 比用 && 更易理解、调试和复用。
- 每个
filter聚焦单一职责,比如“非空”、“成年”、“活跃”、“国内用户” - 顺序不影响结果,但建议按过滤强度排序(先筛掉最多无效数据的条件)
List<User> result = users.stream()
.filter(Objects::nonNull)
.filter(User::isAdult)
.filter(User::isActive)
.filter(u -> "CN".equals(u.getCountry()))
.collect(Collectors.toList());
注意 null 安全与副作用
filter 是无状态、无副作用的操作,但它依赖的谓词不能改变流中元素的状态,也应避免抛出异常或引发 NPE。
立即学习“Java免费学习笔记(深入)”;
- 对可能为
null的字段,提前判空或使用Optional辅助判断 - 不要在
filter的 lambda 中修改对象字段或调用有副作用的方法
// 安全写法:避免 u.getName() 报 NPE
.filter(u -> u != null && u.getName() != null && u.getName().startsWith("A"))
// 或者用 Optional 包装(适合复杂场景)
.filter(u -> Optional.ofNullable(u)
.map(User::getName)
.map(name -> name.startsWith("A"))
.orElse(false))
结合其他算子做链式处理
filter 通常不是终点,而是中间环节。配合 map、sorted、limit 等能写出更流畅的声明式代码。
- 先
filter再map,避免对不满足条件的数据做无谓转换 - 必要时加
distinct去重,尤其在map后可能出现重复 key
List<String> adultNames = users.stream()
.filter(User::isAdult)
.map(User::getName) // 只对成年人取名
.filter(Objects::nonNull)
.distinct()
.sorted()
.limit(10)
.collect(Collectors.toList());


















