Java Predicate 接口
最后修改时间:2025 年 4 月 16 日
java.util.function.Predicate
接口表示一个布尔值函数,用于测试条件。它是一个函数式接口,只有一个抽象方法 test
。Predicate 常用于过滤集合和流。
Predicate
在 Java 8 中引入,并在 JDK 9 中通过新方法进行了增强。它支持函数式编程风格中的条件逻辑。该接口提供了用于逻辑运算和谓词组合的方法。
Predicate 接口概述
Predicate
接口包含一个抽象方法和几个默认和静态方法。关键方法 test
用于评估条件。其他方法支持谓词的逻辑组合。
@FunctionalInterface public interface Predicate<T> { boolean test(T t); default Predicate<T> and(Predicate<? super T> other); default Predicate<T> or(Predicate<? super T> other); default Predicate<T> negate(); static <T> Predicate<T> not(Predicate<? super T> target); static <T> Predicate<T> isEqual(Object targetRef); }
以上代码展示了 Predicate
接口的结构。它使用泛型,其中 T 是输入类型。该接口使用 @FunctionalInterface 注解来表明其单一抽象方法的性质。
Predicate 的基本用法
使用 Predicate 最简单的方式是使用 lambda 表达式。我们在 test 方法中定义要测试的条件。示例检查数字是否为偶数。
package com.zetcode; import java.util.function.Predicate; public class Main { public static void main(String[] args) { // Define a predicate that tests if number is even Predicate<Integer> isEven = n -> n % 2 == 0; // Test the predicate System.out.println("Is 4 even? " + isEven.test(4)); System.out.println("Is 7 even? " + isEven.test(7)); // Predicate using method reference Predicate<String> isEmpty = String::isEmpty; System.out.println("Is empty? " + isEmpty.test("")); } }
此示例演示了使用 lambda 和方法引用的 Predicate 基本用法。isEven 谓词接受 Integer 并返回 boolean。我们用不同的数字来测试它。方法引用为现有方法提供了简洁的语法。
使用 and() 的 Predicate 组合
and
方法使用逻辑 AND 组合两个谓词。生成的谓词仅当两个原始谓词都测试为真时才测试为真。这使复杂条件可以由简单谓词构成。
package com.zetcode; import java.util.function.Predicate; public class Main { public static void main(String[] args) { // First predicate checks if number is positive Predicate<Integer> isPositive = n -> n > 0; // Second predicate checks if number is even Predicate<Integer> isEven = n -> n % 2 == 0; // Combine predicates with AND Predicate<Integer> isPositiveAndEven = isPositive.and(isEven); System.out.println("6 is positive and even? " + isPositiveAndEven.test(6)); System.out.println("-2 is positive and even? " + isPositiveAndEven.test(-2)); System.out.println("3 is positive and even? " + isPositiveAndEven.test(3)); } }
此示例展示了使用 and
的谓词组合。组合后的谓词测试既是正数又是偶数的数字。在我们的测试用例中,只有 6 满足这两个条件。
使用 or() 的 Predicate 组合
or
方法使用逻辑 OR 组合两个谓词。当任一原始谓词测试为真时,生成的谓词测试为真。这对于测试多个可能的条件很有用。
package com.zetcode; import java.util.function.Predicate; public class Main { public static void main(String[] args) { // First predicate checks if string starts with 'A' Predicate<String> startsWithA = s -> s.startsWith("A"); // Second predicate checks if string ends with 'e' Predicate<String> endsWithE = s -> s.endsWith("e"); // Combine predicates with OR Predicate<String> startsOrEnds = startsWithA.or(endsWithE); System.out.println("Apple: " + startsOrEnds.test("Apple")); System.out.println("Orange: " + startsOrEnds.test("Orange")); System.out.println("Banana: " + startsOrEnds.test("Banana")); } }
此示例演示了使用 or
的谓词组合。组合后的谓词测试以 'A' 开头或以 'e' 结尾的字符串。“Apple” 满足这两个条件,“Orange” 满足结尾条件。
使用 negate() 的 Predicate 取反
negate
方法返回一个谓词,该谓词表示原始谓词的逻辑否定。这等同于逻辑 NOT 运算。
package com.zetcode; import java.util.function.Predicate; public class Main { public static void main(String[] args) { // Predicate checks if number is greater than 10 Predicate<Integer> greaterThan10 = n -> n > 10; // Create negated version Predicate<Integer> notGreaterThan10 = greaterThan10.negate(); System.out.println("Is 15 > 10? " + greaterThan10.test(15)); System.out.println("Is 15 not > 10? " + notGreaterThan10.test(15)); System.out.println("Is 5 not > 10? " + notGreaterThan10.test(5)); } }
此示例展示了使用 negate
的谓词取反。取反后的谓词返回原始谓词的相反布尔值。15 大于 10,因此其否定返回 false。
JDK 9+ not() 静态方法
JDK 9 引入了静态 not
方法,作为 negate
的替代方案。它创建一个谓词,该谓词是对提供的谓词的否定。这对于方法引用很有用。
package com.zetcode; import java.util.function.Predicate; import java.util.List; import java.util.Arrays; public class Main { public static void main(String[] args) { List<String> names = Arrays.asList("Alice", "Bob", "", "Charlie", ""); // Filter non-empty strings using not() Predicate<String> nonEmpty = Predicate.not(String::isEmpty); long count = names.stream() .filter(nonEmpty) .count(); System.out.println("Non-empty names: " + count); } }
此示例演示了 JDK 9 的 not
方法。我们创建一个谓词,通过否定 isEmpty 来检查非空字符串。流使用此谓词过滤掉空字符串。结果计算非空名称。
使用 isEqual() 的 Predicate 组合
静态 isEqual
方法创建一个谓词,该谓词测试输入是否等于目标对象。它使用 Objects.equals() 进行比较,安全地处理 null 值。
package com.zetcode; import java.util.function.Predicate; import java.util.List; import java.util.Arrays; public class Main { public static void main(String[] args) { // Create predicate that tests for "admin" Predicate<String> isAdmin = Predicate.isEqual("admin"); List<String> users = Arrays.asList("user1", "admin", "user2", "admin"); long adminCount = users.stream() .filter(isAdmin) .count(); System.out.println("Admin users: " + adminCount); // Works with null values Predicate<String> isNull = Predicate.isEqual(null); System.out.println("Is null? " + isNull.test(null)); } }
此示例展示了 isEqual
的用法。我们创建一个谓词来查找列表中 "admin" 用户。流计算匹配的条目。该示例还演示了 null 安全比较。
复杂的 Predicate 组合
谓词可以使用多种组合方式进行复杂组合。此示例展示了结合 and()、or() 和 negate() 来创建复杂的条件。
package com.zetcode; import java.util.function.Predicate; public class Main { public static void main(String[] args) { Predicate<Integer> isEven = n -> n % 2 == 0; Predicate<Integer> isPositive = n -> n > 0; Predicate<Integer> isMultipleOf3 = n -> n % 3 == 0; // Complex predicate: (positive AND even) OR (multiple of 3) Predicate<Integer> complexPredicate = isPositive.and(isEven).or(isMultipleOf3); System.out.println("4: " + complexPredicate.test(4)); // true (pos+even) System.out.println("-6: " + complexPredicate.test(-6)); // true (multiple of 3) System.out.println("5: " + complexPredicate.test(5)); // false System.out.println("9: " + complexPredicate.test(9)); // true (multiple of 3) } }
此示例创建了一个复杂的谓词,结合了多个条件。该谓词对 (正数且为偶数) 或 (3 的倍数) 的数字测试为真。这展示了强大的谓词组合功能。
来源
在本文中,我们涵盖了 Java Predicate 接口的基本方法和特性,重点介绍了 JDK 9+ 的增强功能。理解这些概念对于函数式编程和流处理至关重要。
作者
列出所有Java教程。