Java BiPredicate 接口
最后修改时间:2025 年 4 月 16 日
java.util.function.BiPredicate
接口表示一个接受两个参数并返回布尔结果的谓词。它是一个函数式接口,具有单个抽象方法 test
。 BiPredicate 用于评估针对两个输入值的条件。
BiPredicate
作为函数式编程实用程序的一部分在 Java 8 中引入。它允许以函数式风格测试具有两个参数的条件。 该接口提供了用于逻辑运算(如 AND、OR 和非)的默认方法。
BiPredicate 接口概述
BiPredicate
接口包含一个抽象方法和三个默认方法。关键方法 test
评估条件。其他方法支持使用逻辑运算进行谓词组合。
@FunctionalInterface public interface BiPredicate<T, U> { boolean test(T t, U u); default BiPredicate<T, U> and(BiPredicate<? super T, ? super U> other); default BiPredicate<T, U> or(BiPredicate<? super T, ? super U> other); default BiPredicate<T, U> negate(); }
上面的代码显示了 BiPredicate
接口的结构。它使用泛型,其中 T 和 U 是输入类型。 接口使用 @FunctionalInterface 注解,以表明其单抽象方法性质。
BiPredicate 的基本用法
使用 BiPredicate 最简单的方法是使用 lambda 表达式。我们定义了要针对两个输入进行测试的条件。示例检查一个字符串是否包含另一个字符串。
package com.zetcode; import java.util.function.BiPredicate; public class Main { public static void main(String[] args) { // Define a BiPredicate that checks if first string contains second BiPredicate<String, String> containsChecker = (str, substr) -> str.contains(substr); // Test the predicate System.out.println("Contains check: " + containsChecker.test("hello world", "hello")); System.out.println("Contains check: " + containsChecker.test("java", "python")); // Using method reference BiPredicate<String, String> equalsChecker = String::equals; System.out.println("Equals check: " + equalsChecker.test("test", "test")); } }
此示例演示了 lambda 和方法引用的基本 BiPredicate 用法。containsChecker 接受两个字符串并返回布尔值。我们测试不同的字符串对。方法引用为现有方法提供了简洁的语法。
使用 AND 组合 BiPredicate
and
方法允许使用逻辑 AND 组合两个谓词。两个谓词都必须计算为 true,组合后的谓词才能返回 true。
package com.zetcode; import java.util.function.BiPredicate; public class Main { public static void main(String[] args) { // First predicate checks if first number is greater than second BiPredicate<Integer, Integer> greaterThan = (a, b) -> a > b; // Second predicate checks if difference is less than 10 BiPredicate<Integer, Integer> diffLessThan10 = (a, b) -> Math.abs(a - b) < 10; // Combine with AND BiPredicate<Integer, Integer> combined = greaterThan.and(diffLessThan10); System.out.println("5 > 3 and diff < 10: " + combined.test(5, 3)); System.out.println("15 > 3 and diff < 10: " + combined.test(15, 3)); } }
此示例展示了使用 and
进行谓词组合。组合谓词检查两个条件。第一个测试通过(5>3 且差值 2<10)。第二个测试失败(15>3 但差值 12 不 <10)。
使用 OR 组合 BiPredicate
or
方法使用逻辑 OR 组合两个谓词。任何一个谓词的计算结果为 true 都会使组合谓词返回 true。
package com.zetcode; import java.util.function.BiPredicate; public class Main { public static void main(String[] args) { // Check if strings have same length BiPredicate<String, String> sameLength = (s1, s2) -> s1.length() == s2.length(); // Check if strings start with same letter BiPredicate<String, String> sameFirstLetter = (s1, s2) -> s1.charAt(0) == s2.charAt(0); // Combine with OR BiPredicate<String, String> combined = sameLength.or(sameFirstLetter); System.out.println("'apple' and 'orange': " + combined.test("apple", "orange")); System.out.println("'banana' and 'berry': " + combined.test("banana", "berry")); } }
此示例演示了 or
组合。第一个测试通过,因为两个字符串都以 'a' 开头(即使长度不同)。第二个测试通过,因为长度相等(即使起始字母不同)。
对 BiPredicate 取反
negate
方法返回一个表示原始谓词的逻辑非的谓词。它反转布尔结果。
package com.zetcode; import java.util.function.BiPredicate; public class Main { public static void main(String[] args) { // Check if number is divisible by another BiPredicate<Integer, Integer> isDivisible = (num, divisor) -> num % divisor == 0; // Create negated version BiPredicate<Integer, Integer> isNotDivisible = isDivisible.negate(); System.out.println("10 divisible by 5: " + isDivisible.test(10, 5)); System.out.println("10 not divisible by 3: " + isNotDivisible.test(10, 3)); } }
此示例展示了谓词的否定。原始谓词检查可 divisibility。取反的版本在数字不可分时返回 true。否定对于反转条件而无需重写它们很有用。
将 BiPredicate 与集合一起使用
BiPredicate 可以与集合一起使用以实现复杂的过滤逻辑。示例基于键和值条件过滤 map 条目。
package com.zetcode; import java.util.HashMap; import java.util.Map; import java.util.function.BiPredicate; public class Main { public static void main(String[] args) { Map<String, Integer> scores = new HashMap<>(); scores.put("Alice", 85); scores.put("Bob", 92); scores.put("Charlie", 78); scores.put("David", 65); // Filter names starting with A-C and scores >= 80 BiPredicate<String, Integer> filter = (name, score) -> name.charAt(0) <= 'C' && score >= 80; System.out.println("Filtered entries:"); scores.forEach((name, score) -> { if (filter.test(name, score)) { System.out.println(name + ": " + score); } }); } }
此示例演示了 BiPredicate 与集合的使用。我们过滤名称以 A-C 开头且分数 80+ 的 map 条目。谓词一起评估键和值条件。这种方法比单独的过滤器更简洁。
BiPredicate 在流过滤中
BiPredicate 可以通过将其转换为 Predicate 来适应流过滤。当流元素包含多个要测试的值时,这很有用。
package com.zetcode; import java.util.List; import java.util.function.BiPredicate; import java.util.stream.Collectors; public class Main { public static void main(String[] args) { record Person(String name, int age) {} List<Person> people = List.of( new Person("Alice", 25), new Person("Bob", 30), new Person("Charlie", 20), new Person("David", 35) ); // BiPredicate to check name length and age BiPredicate<String, Integer> filter = (name, age) -> name.length() > 3 && age >= 25; // Convert BiPredicate to Predicate for stream filter List<Person> filtered = people.stream() .filter(p -> filter.test(p.name(), p.age())) .collect(Collectors.toList()); System.out.println("Filtered people:"); filtered.forEach(p -> System.out.println(p.name() + " - " + p.age())); } }
此示例展示了 BiPredicate 在流操作中的应用。我们根据姓名长度和年龄过滤 Person 对象。lambda 将 BiPredicate 适配到 Predicate,以便在 filter 中使用。这保持了过滤逻辑的清晰分离。
链式多个 BiPredicate
可以链式 BiPredicate 以进行复杂的条件评估。此示例检查产品价格和类别的多个条件。
package com.zetcode; import java.util.function.BiPredicate; public class Main { public static void main(String[] args) { // Check if product is in electronics category BiPredicate<String, Double> isElectronics = (category, price) -> category.equals("Electronics"); // Check if price is in premium range BiPredicate<String, Double> isPremiumPrice = (category, price) -> price > 500; // Check if product is on sale BiPredicate<String, Double> isOnSale = (category, price) -> price < 100; // Complex condition: (Electronics AND premium) OR on sale BiPredicate<String, Double> complexCondition = isElectronics.and(isPremiumPrice).or(isOnSale); System.out.println("Laptop $600: " + complexCondition.test("Electronics", 600.0)); System.out.println("Book $80: " + complexCondition.test("Books", 80.0)); System.out.println("TV $400: " + complexCondition.test("Electronics", 400.0)); } }
此示例演示了复杂的谓词链接。条件对于价格超过 500 美元的电子产品或低于 100 美元的任何产品评估为 true。链接谓词从简单组件创建可读的复杂条件。
来源
在本文中,我们介绍了 Java BiPredicate 接口的基本方法和特性。了解这些概念对于在现代 Java 应用程序中使用双参数条件进行函数式编程至关重要。
作者
列出所有Java教程。