原文: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

  1. package com.zetcode;
  2. import java.util.List;
  3. import java.util.function.Predicate;
  4. class BiggerThanFive<E> implements Predicate<Integer> {
  5. @Override
  6. public boolean test(Integer v) {
  7. Integer five = 5;
  8. return v > five;
  9. }
  10. }
  11. public class JavaPredicateEx {
  12. public static void main(String[] args) {
  13. List<Integer> nums = List.of(2, 3, 1, 5, 6, 7, 8, 9, 12);
  14. BiggerThanFive<Integer> btf = new BiggerThanFive<>();
  15. nums.stream().filter(btf).forEach(System.out::println);
  16. }
  17. }

在示例中,谓词用于过滤整数。

  1. class BiggerThanFive<E> implements Predicate<Integer> {
  2. @Override
  3. public boolean test(Integer v) {
  4. Integer five = 5;
  5. return v > five;
  6. }
  7. }

这是实现Predicate<Integer>接口的 Java 类。 对于大于 5 的值,其test()方法返回 true。

  1. List<Integer> nums = List.of(2, 3, 1, 5, 6, 7, 8, 9, 12);

我们有一个整数值列表。

  1. BiggerThanFive<Integer> btf = new BiggerThanFive<>();

实例化了BiggerThanFive

  1. nums.stream().filter(btf).forEach(System.out::println);

谓词对象将传递给filter()方法,以从列表中获取所有大于 5 的值。

  1. 6
  2. 7
  3. 8
  4. 9
  5. 12

这是输出。

使用 lambda 和谓词

Java lambda 表达式简化了 Java 谓词的创建。

com/zetcode/JavaPredicateEx2.java

  1. package com.zetcode;
  2. import java.util.List;
  3. import java.util.function.Predicate;
  4. public class JavaPredicateEx2 {
  5. public static void main(String[] args) {
  6. List<Integer> nums = List.of(2, 3, 1, 5, 6, 7, 8, 9, 12);
  7. Predicate<Integer> btf = n -> n > 5;
  8. nums.stream().filter(btf).forEach(System.out::println);
  9. }
  10. }

该示例过滤整数值; 这次我们使用 Java lambda 表达式,这使代码更短。

  1. Predicate<Integer> btf = n -> n > 5;

这是创建谓词的单一语言。

Java 谓词示例 II

下一个示例使用具有两个条件的谓词。

com/zetcode/Country.java

  1. package com.zetcode;
  2. public class Country {
  3. private String name;
  4. private int population;
  5. public Country(String name, int population) {
  6. this.name = name;
  7. this.population = population;
  8. }
  9. public String getName() {
  10. return name;
  11. }
  12. public void setName(String name) {
  13. this.name = name;
  14. }
  15. public int getPopulation() {
  16. return population;
  17. }
  18. public void setPopulation(int population) {
  19. this.population = population;
  20. }
  21. @Override
  22. public String toString() {
  23. return "Country{" + "name=" + name +
  24. ", population=" + population + '}';
  25. }
  26. }

我们有一个Country类; 它具有namepopulation属性。

com/zetcode/JavaPredicateEx3.java

  1. package com.zetcode;
  2. import java.util.ArrayList;
  3. import java.util.List;
  4. import java.util.function.Predicate;
  5. public class JavaPredicateEx3 {
  6. public static void main(String[] args) {
  7. List<Country> countries = new ArrayList<>();
  8. countries.add(new Country("Iran", 80840713));
  9. countries.add(new Country("Hungary", 9845000));
  10. countries.add(new Country("Poland", 38485000));
  11. countries.add(new Country("India", 1342512000));
  12. countries.add(new Country("Latvia", 1978000));
  13. countries.add(new Country("Vietnam", 95261000));
  14. countries.add(new Country("Sweden", 9967000));
  15. countries.add(new Country("Iceland", 337600));
  16. countries.add(new Country("Israel", 8622000));
  17. Predicate<Country> p1 = c -> c.getName().startsWith("I") &&
  18. c.getPopulation() > 10000000;
  19. countries.stream().filter(p1).forEach(System.out::println);
  20. }
  21. }

在示例中,我们创建了一个国家列表。 我们按国家名称和人口过滤列表。

  1. Predicate<Country> p1 = c -> c.getName().startsWith("I") &&
  2. c.getPopulation() > 10000000;

对于以"I"开头且人口超过一千万的国家,该谓词返回正确。

  1. Country{name=Iran, population=80840713}
  2. Country{name=India, population=1342512000}

名单中有两个国家满足条件:伊朗和印度。

Java IntPredicate

IntPredicate表示一个int值自变量的谓词。 这是Predicate<E>int消耗型原始类型特化。

com/zetcode/IntPredicateEx.java

  1. package com.zetcode;
  2. import java.util.Arrays;
  3. import java.util.function.IntPredicate;
  4. public class IntPredicateEx {
  5. public static void main(String[] args) {
  6. int[] nums = { 2, 3, 1, 5, 6, 7, 8, 9, 12 };
  7. IntPredicate p = n -> n > 5;
  8. Arrays.stream(nums).filter(p).forEach(System.out::println);
  9. }
  10. }

该示例使用filter()IntPredicate过滤int值数组。

  1. int nums[] = { 2, 3, 1, 5, 6, 7, 8, 9, 12 };

我们定义一个整数数组。

  1. IntPredicate p = n -> n > 5;

创建了IntPredicate; 如果int值大于 5,则返回true

  1. Arrays.stream(nums).filter(p).forEach(System.out::println);

我们从数组创建一个流并过滤元素。 filter()方法接收谓词作为参数。

组合谓词

使用and()or()方法,我们可以用 Java 编写谓词。

com/zetcode/JavaPredicateCompose.java

  1. package com.zetcode;
  2. import java.util.Arrays;
  3. import java.util.function.IntPredicate;
  4. public class JavaPredicateCompose {
  5. public static void main(String[] args) {
  6. int[] nums = {2, 3, 1, 5, 6, 7, 8, 9, 12};
  7. IntPredicate p1 = n -> n > 3;
  8. IntPredicate p2 = n -> n < 9;
  9. Arrays.stream(nums).filter(p1.and(p2)).forEach(System.out::println);
  10. System.out.println("**********");
  11. IntPredicate p3 = n -> n == 6;
  12. IntPredicate p4 = n -> n == 9;
  13. Arrays.stream(nums).filter(p3.or(p4)).forEach(System.out::println);
  14. }
  15. }

该示例使用IntPredicates的组成过滤数据。

  1. IntPredicate p1 = n -> n > 3;
  2. IntPredicate p2 = n -> n < 9;
  3. Arrays.stream(nums).filter(p1.and(p2)).forEach(System.out::println);

我们将两个谓词与and()方法结合使用; 我们得到大于 3 且小于 9 的整数。

  1. IntPredicate p3 = n -> n == 6;
  2. IntPredicate p4 = n -> n == 9;
  3. Arrays.stream(nums).filter(p3.or(p4)).forEach(System.out::println);

使用or()方法,我们得到的值等于 6 或 9。

  1. 5
  2. 6
  3. 7
  4. 8
  5. **********
  6. 6
  7. 9

这是输出。

否定谓词

negate()方法返回一个谓词,该谓词表示给定谓词的逻辑非。

com/zetcode/JavaPredicateNegate.java

  1. package com.zetcode;
  2. import java.util.Arrays;
  3. import java.util.function.IntPredicate;
  4. public class JavaPredicateNegate {
  5. public static void main(String[] args) {
  6. int[] nums = {2, 3, 1, 5, 6, 7, 8, 9, 12};
  7. IntPredicate p = n -> n > 5;
  8. Arrays.stream(nums).filter(p).forEach(System.out::println);
  9. System.out.println("**********");
  10. Arrays.stream(nums).filter(p.negate()).forEach(System.out::println);
  11. }
  12. }

该示例演示了negate()方法的用法。

  1. IntPredicate p = n -> n > 5;

我们有一个谓词,对于大于 5 的值返回true

  1. Arrays.stream(nums).filter(p).forEach(System.out::println);

我们过滤所有大于 5 的整数。

  1. Arrays.stream(nums).filter(p.negate()).forEach(System.out::println);

使用negate()方法,我们得到相反的结果:值小于或等于 4。

  1. 6
  2. 7
  3. 8
  4. 9
  5. 12
  6. **********
  7. 2
  8. 3
  9. 1
  10. 5

这是示例的输出。

Java 谓词作为方法参数

谓词可以作为方法参数传递。

com/zetcode/PredicateMethodParam.java

  1. package com.zetcode;
  2. import java.util.List;
  3. import java.util.function.Predicate;
  4. import java.util.stream.Collectors;
  5. public class PredicateMethodParam {
  6. public static void main(String args[]) {
  7. List<Integer> list = List.of(1, 2, 3, 4, 5, 6, 7,
  8. 8, 9, 10, 11, 12);
  9. List<Integer> all = eval(list, n -> true);
  10. System.out.println(all);
  11. List<Integer> evenValues = eval(list, n -> n % 2 == 0);
  12. System.out.println(evenValues);
  13. List<Integer> greaterThanSix = eval(list, n -> n > 6);
  14. System.out.println(greaterThanSix);
  15. }
  16. private static List<Integer> eval(List<Integer> values,
  17. Predicate<Integer> predicate) {
  18. return values.stream().filter(predicate)
  19. .collect(Collectors.toList());
  20. }
  21. }

在示例中,我们将谓词函数作为第二个参数传递给eval()方法。

在本教程中,我们使用了 Java 谓词。 您可能也对相关教程感兴趣: Java 教程Java 中的HashMap迭代Java ArrayList教程Java HashSet教程Java static关键字Java8 forEach教程读取 Java 中的文本文件读取和写入 Java 中的 ICO 图像

列出所有 Java 教程