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教程。