predicate 是 java 8 的函数式接口,用于封装单一输入、布尔输出的条件判断逻辑,支持 lambda 定义、组合(and/or/negate)及在 stream.filter() 和 collection.removeif() 中应用,强调可复用性与可维护性。

Predicate 是 Java 8 引入的函数式接口,核心就是用 test(T t) 方法做单一输入、布尔输出的条件判断。它不是语法糖,而是把“是否满足某条件”这个动作封装成可复用、可传递、可拼装的对象。
定义一个 Predicate 判断逻辑
最常用方式是用 Lambda 表达式直接写判断规则,类型由泛型 T 确定:
-
判断字符串长度是否超过 5:
Predicate<string> isLong = s -> s != null && s.length() > 5;</string> -
判断用户是否成年且活跃:
Predicate<user> isEligible = u -> u != null && u.getAge() >= 18 && u.isActive();</user> - 避免空指针:Lambda 内必须显式判空,否则传入 null 会抛 NPE
组合多个条件(and/or/negate)
Predicate 自带短路逻辑组合能力,语义清晰,行为可控:
-
isAdult.and(isActive)→ 相当于&&,左边 false 就不执行右边 -
isVIP.or(isPremium)→ 相当于||,左边 true 就跳过右边 -
isEmpty.negate()→ 返回新 Predicate,逻辑取反,但原 test 仍会执行 - 组合链别太长,比如
a.and(b).or(c).negate()可读性差,建议拆解或命名中间变量
在集合操作中真正用起来
它不是摆设,主要落地在两类场景:
-
Stream.filter():生成新集合 ——
list.stream().filter(isEligible).collect(Collectors.toList()) -
Collection.removeIf():修改原集合 ——
users.removeIf(u -> u.getAge() 注意:这是「移除满足条件的」,不是筛选 - 两者都接收 Predicate,但语义和副作用完全不同,不能混用
封装复杂判断,提升可维护性
逻辑一多,就别堆在 lambda 里:
- 提取为私有方法:
private boolean checkCreditScore(User u) { ... },再用this::checkCreditScore引用 - 写静态工厂方法:
static Predicate<string> contains(String keyword) { return s -> s != null && s.contains(keyword); }</string> - 避免自定义类塞状态字段(如
MinLengthPredicate.min),除非明确需要线程安全封装
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











