Java Predicate接口
什么是Predicate接口?
Predicate接口是Java 8引入的函数式接口,位于java.util.function
包中。这个接口代表一个接受单个输入参数并返回布尔值的函数。简单来说,它是一个用于测试对象是否满足特定条件的断言接口。
Predicate接口的核心方法是:
boolean test(T t);
这个方法接受一个类型为T的对象,对它进行某种条件测试,并返回一个布尔值,表示该对象是否满足测试条件。
函数式接口是只包含一个抽象方法的接口。Java 8中引入的这些接口可以与Lambda表达式一起使用,使代码更加简洁。
Predicate接口的基本用法
创建和使用Predicate
让我们看一个简单的例子,使用Predicate检查一个数字是否为正数:
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的逻辑与(&&)组合:
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的逻辑或(||)组合:
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的逻辑非(!):
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:
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接口在处理集合时特别有用,比如在过滤集合元素时:
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来验证用户输入:
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表达式:
Predicate<Integer> isPositive = n -> n > 0;
使用匿名类:
Predicate<Integer> isPositive = new Predicate<Integer>() {
@Override
public boolean test(Integer n) {
return n > 0;
}
};
显然,Lambda表达式使代码更加简洁和可读。
总结
Java Predicate接口是函数式编程中一个非常有用的工具,它允许我们:
- 创建接受参数并返回布尔值的函数
- 使用
and()
、or()
和negate()
方法组合多个条件 - 简化集合过滤和条件判断的代码
- 使代码更加模块化和可复用
Predicate接口是Java 8函数式编程的重要组成部分,熟练掌握它可以帮助你编写更简洁、更优雅的代码。
练习
- 创建一个Predicate来检查字符串是否是回文(正着读和倒着读相同)
- 编写一个方法,接受一个整数列表和一个Predicate,返回符合条件的元素数量
- 使用Predicate创建一个简单的文件过滤器,过滤出所有以".txt"结尾的文件名
更多资源
- Java官方文档中的
Predicate<T>
接口 - 学习Java 8中的其他函数式接口,如
Function
、Consumer
和Supplier
- 探索如何结合Stream API和Predicate接口处理集合数据
Predicate接口是函数式编程的入门概念之一。掌握它将为学习更复杂的函数式编程概念奠定基础。