跳到主要内容

Java Predicate接口

什么是Predicate接口?

Predicate接口是Java 8引入的函数式接口,位于java.util.function包中。这个接口代表一个接受单个输入参数并返回布尔值的函数。简单来说,它是一个用于测试对象是否满足特定条件的断言接口。

Predicate接口的核心方法是:

java
boolean test(T t);

这个方法接受一个类型为T的对象,对它进行某种条件测试,并返回一个布尔值,表示该对象是否满足测试条件。

提示

函数式接口是只包含一个抽象方法的接口。Java 8中引入的这些接口可以与Lambda表达式一起使用,使代码更加简洁。

Predicate接口的基本用法

创建和使用Predicate

让我们看一个简单的例子,使用Predicate检查一个数字是否为正数:

java
import java.util.function.Predicate;

public class PredicateExample {
public static void main(String[] args) {
// 创建一个判断整数是否为正数的Predicate
Predicate<Integer> isPositive = n -> n > 0;

// 测试Predicate
System.out.println(isPositive.test(5)); // 输出: true
System.out.println(isPositive.test(-5)); // 输出: false
System.out.println(isPositive.test(0)); // 输出: false
}
}

在上面的例子中,我们创建了一个Predicate实例,它测试一个整数是否大于0。然后我们使用test()方法来测试不同的输入值。

Predicate接口的默认方法

Predicate接口除了test()方法外,还提供了几个默认方法,可以用于组合多个Predicate:

1. and()

and()方法返回一个新的Predicate,它是两个Predicate的逻辑与(&&)组合:

java
Predicate<Integer> isPositive = n -> n > 0;
Predicate<Integer> isEven = n -> n % 2 == 0;

// 组合两个Predicate: 检查数字是否为正偶数
Predicate<Integer> isPositiveEven = isPositive.and(isEven);

System.out.println(isPositiveEven.test(4)); // 输出: true
System.out.println(isPositiveEven.test(3)); // 输出: false
System.out.println(isPositiveEven.test(-2)); // 输出: false

2. or()

or()方法返回一个新的Predicate,它是两个Predicate的逻辑或(||)组合:

java
Predicate<Integer> isPositive = n -> n > 0;
Predicate<Integer> isZero = n -> n == 0;

// 组合两个Predicate: 检查数字是否为非负数
Predicate<Integer> isNonNegative = isPositive.or(isZero);

System.out.println(isNonNegative.test(5)); // 输出: true
System.out.println(isNonNegative.test(0)); // 输出: true
System.out.println(isNonNegative.test(-5)); // 输出: false

3. negate()

negate()方法返回一个新的Predicate,它是原Predicate的逻辑非(!):

java
Predicate<Integer> isPositive = n -> n > 0;

// 取反: 检查数字是否为非正数
Predicate<Integer> isNonPositive = isPositive.negate();

System.out.println(isNonPositive.test(5)); // 输出: false
System.out.println(isNonPositive.test(0)); // 输出: true
System.out.println(isNonPositive.test(-5)); // 输出: true

静态方法isEqual()

Predicate接口还提供了一个静态方法isEqual(),它返回一个测试对象是否等于给定对象的Predicate:

java
import java.util.function.Predicate;

public class PredicateExample {
public static void main(String[] args) {
String reference = "Hello";

Predicate<String> isEqual = Predicate.isEqual(reference);

System.out.println(isEqual.test("Hello")); // 输出: true
System.out.println(isEqual.test("World")); // 输出: false
}
}

Predicate在集合中的应用

Predicate接口在处理集合时特别有用,比如在过滤集合元素时:

java
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;

public class PredicateWithCollections {
public static void main(String[] args) {
List<String> names = Arrays.asList("John", "Jane", "Jack", "Joe", "Jill");

// 创建一个检查字符串是否以'J'开头且长度为4的Predicate
Predicate<String> startsWithJ = s -> s.startsWith("J");
Predicate<String> length4 = s -> s.length() == 4;
Predicate<String> filter = startsWithJ.and(length4);

// 使用filter过滤名字列表
List<String> filteredNames = names.stream()
.filter(filter)
.collect(Collectors.toList());

System.out.println(filteredNames); // 输出: [John, Jack, Jill]
}
}

实际案例:用户输入验证

让我们看一个更实际的例子,使用Predicate来验证用户输入:

java
import java.util.function.Predicate;

public class UserInputValidator {
public static void main(String[] args) {
// 测试邮箱和密码
String email = "user@example.com";
String password = "Pass123";

if (isValidInput(email, password)) {
System.out.println("输入有效,继续处理...");
} else {
System.out.println("无效输入,请检查邮箱和密码格式");
}
}

public static boolean isValidInput(String email, String password) {
// 邮箱验证: 必须包含@符号且长度大于5
Predicate<String> isValidEmail = e -> e != null && e.contains("@") && e.length() > 5;

// 密码验证: 长度至少6位,且必须包含至少一个数字
Predicate<String> isValidPassword = p -> p != null && p.length() >= 6 && p.matches(".*\\d.*");

// 组合验证条件
return isValidEmail.test(email) && isValidPassword.test(password);
}
}

输出:

输入有效,继续处理...

Predicate与Lambda表达式的关系

Predicate接口是专门设计来与Lambda表达式一起使用的。Lambda表达式提供了创建Predicate实例的简洁方式,而无需编写实现接口的匿名类。

以下两种方式创建Predicate的效果是相同的:

使用Lambda表达式:

java
Predicate<Integer> isPositive = n -> n > 0;

使用匿名类:

java
Predicate<Integer> isPositive = new Predicate<Integer>() {
@Override
public boolean test(Integer n) {
return n > 0;
}
};

显然,Lambda表达式使代码更加简洁和可读。

总结

Java Predicate接口是函数式编程中一个非常有用的工具,它允许我们:

  1. 创建接受参数并返回布尔值的函数
  2. 使用and()or()negate()方法组合多个条件
  3. 简化集合过滤和条件判断的代码
  4. 使代码更加模块化和可复用

Predicate接口是Java 8函数式编程的重要组成部分,熟练掌握它可以帮助你编写更简洁、更优雅的代码。

练习

  1. 创建一个Predicate来检查字符串是否是回文(正着读和倒着读相同)
  2. 编写一个方法,接受一个整数列表和一个Predicate,返回符合条件的元素数量
  3. 使用Predicate创建一个简单的文件过滤器,过滤出所有以".txt"结尾的文件名

更多资源

  • Java官方文档中的Predicate<T>接口
  • 学习Java 8中的其他函数式接口,如FunctionConsumerSupplier
  • 探索如何结合Stream API和Predicate接口处理集合数据
备注

Predicate接口是函数式编程的入门概念之一。掌握它将为学习更复杂的函数式编程概念奠定基础。