💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
# Java 谓词 原文:http://zetcode.com/java/predicate/ Java 谓词教程展示了如何在 Java 中使用谓词。 使用谓词,我们可以创建更清晰易读的代码。 谓词还有助于创建更好的测试。 ## 谓词 谓词的一般含义是对正确或错误的陈述。 在编程中,谓词表示返回布尔值的单个参数函数。 ## Java 谓词 Java 中的谓词通过接口实现。 `Predicate<T>`是表示单个参数函数的通用函数接口,该函数返回布尔值。 它位于`java.util.function`包中。 它包含`test(T t)`方法,该方法求值给定参数上的谓词。 在 Java 中,我们没有独立的函数。 此外,方法不是一等公民。 (不能将它们添加到集合中或作为参数传递给方法。)因此,我们定义接口并从这些接口创建对象。 然后可以将此类对象传递给`Iterables.filter()`之类的方法。 使用 Java lambda,使用谓词要容易得多。 ## Java 谓词示例 以下示例创建一个简单的 Java 谓词。 `com/zetcode/JavaPredicateEx.java` ```java package com.zetcode; import java.util.List; import java.util.function.Predicate; class BiggerThanFive<E> implements Predicate<Integer> { @Override public boolean test(Integer v) { Integer five = 5; return v > five; } } public class JavaPredicateEx { public static void main(String[] args) { List<Integer> nums = List.of(2, 3, 1, 5, 6, 7, 8, 9, 12); BiggerThanFive<Integer> btf = new BiggerThanFive<>(); nums.stream().filter(btf).forEach(System.out::println); } } ``` 在示例中,谓词用于过滤整数。 ```java class BiggerThanFive<E> implements Predicate<Integer> { @Override public boolean test(Integer v) { Integer five = 5; return v > five; } } ``` 这是实现`Predicate<Integer>`接口的 Java 类。 对于大于 5 的值,其`test()`方法返回 true。 ```java List<Integer> nums = List.of(2, 3, 1, 5, 6, 7, 8, 9, 12); ``` 我们有一个整数值列表。 ```java BiggerThanFive<Integer> btf = new BiggerThanFive<>(); ``` 实例化了`BiggerThanFive`。 ```java nums.stream().filter(btf).forEach(System.out::println); ``` 谓词对象将传递给`filter()`方法,以从列表中获取所有大于 5 的值。 ```java 6 7 8 9 12 ``` 这是输出。 ## 使用 lambda 和谓词 Java lambda 表达式简化了 Java 谓词的创建。 `com/zetcode/JavaPredicateEx2.java` ```java package com.zetcode; import java.util.List; import java.util.function.Predicate; public class JavaPredicateEx2 { public static void main(String[] args) { List<Integer> nums = List.of(2, 3, 1, 5, 6, 7, 8, 9, 12); Predicate<Integer> btf = n -> n > 5; nums.stream().filter(btf).forEach(System.out::println); } } ``` 该示例过滤整数值; 这次我们使用 Java lambda 表达式,这使代码更短。 ```java Predicate<Integer> btf = n -> n > 5; ``` 这是创建谓词的单一语言。 ## Java 谓词示例 II 下一个示例使用具有两个条件的谓词。 `com/zetcode/Country.java` ```java package com.zetcode; public class Country { private String name; private int population; public Country(String name, int population) { this.name = name; this.population = population; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getPopulation() { return population; } public void setPopulation(int population) { this.population = population; } @Override public String toString() { return "Country{" + "name=" + name + ", population=" + population + '}'; } } ``` 我们有一个`Country`类; 它具有`name`和`population`属性。 `com/zetcode/JavaPredicateEx3.java` ```java package com.zetcode; import java.util.ArrayList; import java.util.List; import java.util.function.Predicate; public class JavaPredicateEx3 { public static void main(String[] args) { List<Country> countries = new ArrayList<>(); countries.add(new Country("Iran", 80840713)); countries.add(new Country("Hungary", 9845000)); countries.add(new Country("Poland", 38485000)); countries.add(new Country("India", 1342512000)); countries.add(new Country("Latvia", 1978000)); countries.add(new Country("Vietnam", 95261000)); countries.add(new Country("Sweden", 9967000)); countries.add(new Country("Iceland", 337600)); countries.add(new Country("Israel", 8622000)); Predicate<Country> p1 = c -> c.getName().startsWith("I") && c.getPopulation() > 10000000; countries.stream().filter(p1).forEach(System.out::println); } } ``` 在示例中,我们创建了一个国家列表。 我们按国家名称和人口过滤列表。 ```java Predicate<Country> p1 = c -> c.getName().startsWith("I") && c.getPopulation() > 10000000; ``` 对于以`"I"`开头且人口超过一千万的国家,该谓词返回正确。 ```java Country{name=Iran, population=80840713} Country{name=India, population=1342512000} ``` 名单中有两个国家满足条件:伊朗和印度。 ## Java `IntPredicate` `IntPredicate`表示一个`int`值自变量的谓词。 这是`Predicate<E>`的`int`消耗型原始类型特化。 `com/zetcode/IntPredicateEx.java` ```java package com.zetcode; import java.util.Arrays; import java.util.function.IntPredicate; public class IntPredicateEx { public static void main(String[] args) { int[] nums = { 2, 3, 1, 5, 6, 7, 8, 9, 12 }; IntPredicate p = n -> n > 5; Arrays.stream(nums).filter(p).forEach(System.out::println); } } ``` 该示例使用`filter()`和`IntPredicate`过滤`int`值数组。 ```java int nums[] = { 2, 3, 1, 5, 6, 7, 8, 9, 12 }; ``` 我们定义一个整数数组。 ```java IntPredicate p = n -> n > 5; ``` 创建了`IntPredicate`; 如果`int`值大于 5,则返回`true`。 ```java Arrays.stream(nums).filter(p).forEach(System.out::println); ``` 我们从数组创建一个流并过滤元素。 `filter()`方法接收谓词作为参数。 ## 组合谓词 使用`and()`和`or()`方法,我们可以用 Java 编写谓词。 `com/zetcode/JavaPredicateCompose.java` ```java package com.zetcode; import java.util.Arrays; import java.util.function.IntPredicate; public class JavaPredicateCompose { public static void main(String[] args) { int[] nums = {2, 3, 1, 5, 6, 7, 8, 9, 12}; IntPredicate p1 = n -> n > 3; IntPredicate p2 = n -> n < 9; Arrays.stream(nums).filter(p1.and(p2)).forEach(System.out::println); System.out.println("**********"); IntPredicate p3 = n -> n == 6; IntPredicate p4 = n -> n == 9; Arrays.stream(nums).filter(p3.or(p4)).forEach(System.out::println); } } ``` 该示例使用`IntPredicates`的组成过滤数据。 ```java IntPredicate p1 = n -> n > 3; IntPredicate p2 = n -> n < 9; Arrays.stream(nums).filter(p1.and(p2)).forEach(System.out::println); ``` 我们将两个谓词与`and()`方法结合使用; 我们得到大于 3 且小于 9 的整数。 ```java IntPredicate p3 = n -> n == 6; IntPredicate p4 = n -> n == 9; Arrays.stream(nums).filter(p3.or(p4)).forEach(System.out::println); ``` 使用`or()`方法,我们得到的值等于 6 或 9。 ```java 5 6 7 8 ********** 6 9 ``` 这是输出。 ## 否定谓词 `negate()`方法返回一个谓词,该谓词表示给定谓词的逻辑非。 `com/zetcode/JavaPredicateNegate.java` ```java package com.zetcode; import java.util.Arrays; import java.util.function.IntPredicate; public class JavaPredicateNegate { public static void main(String[] args) { int[] nums = {2, 3, 1, 5, 6, 7, 8, 9, 12}; IntPredicate p = n -> n > 5; Arrays.stream(nums).filter(p).forEach(System.out::println); System.out.println("**********"); Arrays.stream(nums).filter(p.negate()).forEach(System.out::println); } } ``` 该示例演示了`negate()`方法的用法。 ```java IntPredicate p = n -> n > 5; ``` 我们有一个谓词,对于大于 5 的值返回`true`。 ```java Arrays.stream(nums).filter(p).forEach(System.out::println); ``` 我们过滤所有大于 5 的整数。 ```java Arrays.stream(nums).filter(p.negate()).forEach(System.out::println); ``` 使用`negate()`方法,我们得到相反的结果:值小于或等于 4。 ```java 6 7 8 9 12 ********** 2 3 1 5 ``` 这是示例的输出。 ## Java 谓词作为方法参数 谓词可以作为方法参数传递。 `com/zetcode/PredicateMethodParam.java` ```java package com.zetcode; import java.util.List; import java.util.function.Predicate; import java.util.stream.Collectors; public class PredicateMethodParam { public static void main(String args[]) { List<Integer> list = List.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12); List<Integer> all = eval(list, n -> true); System.out.println(all); List<Integer> evenValues = eval(list, n -> n % 2 == 0); System.out.println(evenValues); List<Integer> greaterThanSix = eval(list, n -> n > 6); System.out.println(greaterThanSix); } private static List<Integer> eval(List<Integer> values, Predicate<Integer> predicate) { return values.stream().filter(predicate) .collect(Collectors.toList()); } } ``` 在示例中,我们将谓词函数作为第二个参数传递给`eval()`方法。 在本教程中,我们使用了 Java 谓词。 您可能也对相关教程感兴趣: [Java 教程](/lang/java/), [Java 中的`HashMap`迭代](/java/hashmapiterate/), [Java `ArrayList`教程](/java/arraylist/), [Java `HashSet`教程](/java/hashset), [Java `static`关键字](/java/statickeyword/), [Java8 `forEach`教程](/articles/java8foreach/),[读取 Java 中的文本文件](/java/readtext/)和[读取和写入 Java 中的 ICO 图像](/articles/javaico/)。 列出[所有 Java 教程](/all/#java)。