本文目录导读:

在 Java 中,Predicate 是 java.util.function 包下的一个函数式接口,用于判断(返回布尔值),它常用于过滤、条件检查等场景。
下面通过几个经典的案例来展示它的用法。
基础用法:过滤集合
场景:从列表中筛选出满足条件的元素。
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;
public class PredicateBasic {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
// 定义条件:偶数
Predicate<Integer> isEven = n -> n % 2 == 0;
// 定义条件:大于5
Predicate<Integer> greaterThan5 = n -> n > 5;
// 筛选偶数
List<Integer> evens = numbers.stream()
.filter(isEven)
.collect(Collectors.toList());
System.out.println("偶数: " + evens); // [2, 4, 6, 8, 10]
// 组合条件:偶数 大于5
List<Integer> evenAndGreater = numbers.stream()
.filter(isEven.and(greaterThan5))
.collect(Collectors.toList());
System.out.println("偶数且>5: " + evenAndGreater); // [6, 8, 10]
}
}
组合 Predicate:and / or / negate
场景:动态拼装复杂的业务判断逻辑。
import java.util.function.Predicate;
public class PredicateCombine {
public static void main(String[] args) {
// 条件1:年龄大于18
Predicate<Integer> isAdult = age -> age >= 18;
// 条件2:年龄小于60(非退休)
Predicate<Integer> notRetired = age -> age < 60;
// 组合:成年人 且 未退休
Predicate<Integer> workingAdult = isAdult.and(notRetired);
// 组合:未成年人 或 已退休
Predicate<Integer> seniorOrMinor = isAdult.negate().or(notRetired.negate());
System.out.println("25岁是否在职成人: " + workingAdult.test(25)); // true
System.out.println("65岁是否退休/未成年: " + seniorOrMinor.test(65)); // true
System.out.println("15岁是否退休/未成年: " + seniorOrMinor.test(15)); // true
}
}
用作工具方法参数(高阶函数)
场景:将 Predicate 作为参数传递,减少重复代码。
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
class Person {
String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return name + "(" + age + ")";
}
}
public class PredicateUtility {
// 通用过滤器:根据任意条件过滤
public static List<Person> filter(List<Person> list, Predicate<Person> predicate) {
List<Person> result = new ArrayList<>();
for (Person p : list) {
if (predicate.test(p)) {
result.add(p);
}
}
return result;
}
public static void main(String[] args) {
List<Person> people = List.of(
new Person("Alice", 25),
new Person("Bob", 17),
new Person("Charlie", 35)
);
// 筛选成年人
List<Person> adults = filter(people, p -> p.age >= 18);
System.out.println("成年人: " + adults); // [Alice(25), Charlie(35)]
// 筛选名字以 A 开头的人
List<Person> nameStartsWithA = filter(people, p -> p.name.startsWith("A"));
System.out.println("名字以A开头: " + nameStartsWithA); // [Alice(25)]
}
}
结合 Objects.nonNull 处理空值
场景:过滤掉 null 元素。
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.function.Predicate;
import java.util.stream.Collectors;
public class PredicateNonNull {
public static void main(String[] args) {
List<String> items = Arrays.asList("apple", null, "banana", null, "cherry");
// 使用 Predicate.isEqual 或 Objects::nonNull
List<String> nonNullItems = items.stream()
.filter(Objects::nonNull)
.collect(Collectors.toList());
System.out.println(nonNullItems); // [apple, banana, cherry]
// 也可以使用 Predicate.not()(Java 11+)
Predicate<String> isNull = Objects::isNull;
List<String> nonNullItems2 = items.stream()
.filter(Predicate.not(isNull))
.collect(Collectors.toList());
System.out.println(nonNullItems2); // [apple, banana, cherry]
}
}
复杂业务:动态条件组合(工厂模式)
场景:根据用户输入动态构建查询条件。
import java.util.function.Predicate;
public class PredicateFactory {
public static Predicate<String> buildCondition(String keyword, boolean caseSensitive) {
Predicate<String> containsKeyword = text -> caseSensitive ?
text.contains(keyword) : text.toLowerCase().contains(keyword.toLowerCase());
if (keyword == null || keyword.isEmpty()) {
return text -> true; // 无条件(全部通过)
}
return containsKeyword;
}
public static void main(String[] args) {
Predicate<String> strict = buildCondition("JAVA", true);
Predicate<String> loose = buildCondition("JAVA", false);
System.out.println("严格匹配 'hello JAVA world': " + strict.test("hello JAVA world")); // true
System.out.println("严格匹配 'hello java world': " + strict.test("hello java world")); // false
System.out.println("宽松匹配 'hello java world': " + loose.test("hello java world")); // true
}
}
| 场景 | 核心要点 |
|---|---|
| 集合过滤 | 搭配 stream().filter() 使用 |
| 组合逻辑 | and()、or()、negate() 方法 |
| 参数传递 | 避免代码重复,实现通用的过滤工具 |
| 空值处理 | Objects::nonNull 或 Predicate.not(...) |
| 动态条件 | 通过工厂方法动态生成 Predicate 实例 |
核心优势:把判断逻辑作为“一等公民”传递,让代码更简洁、灵活,符合函数式编程思想,在你需要“定义一种匹配规则,并在任何地方复用”的时候,Predicate 是最佳选择。