跳转至

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

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);
    }
}

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

class BiggerThanFive<E> implements Predicate<Integer> {

    @Override
    public boolean test(Integer v) {

        Integer five = 5;

        return v > five;
    }
}

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

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

我们有一个整数值列表。

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

实例化了BiggerThanFive

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

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

6
7
8
9
12

这是输出。

使用 lambda 和谓词

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

com/zetcode/JavaPredicateEx2.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 表达式,这使代码更短。

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

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

Java 谓词示例 II

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

com/zetcode/Country.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类; 它具有namepopulation属性。

com/zetcode/JavaPredicateEx3.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);
    }
}

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

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

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

Country{name=Iran, population=80840713}
Country{name=India, population=1342512000}

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

Java IntPredicate

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

com/zetcode/IntPredicateEx.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值数组。

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

我们定义一个整数数组。

IntPredicate p = n -> n > 5;

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

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

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

组合谓词

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

com/zetcode/JavaPredicateCompose.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的组成过滤数据。

IntPredicate p1 = n -> n > 3;
IntPredicate p2 = n -> n < 9;

Arrays.stream(nums).filter(p1.and(p2)).forEach(System.out::println);

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

IntPredicate p3 = n -> n == 6;
IntPredicate p4 = n -> n == 9;

Arrays.stream(nums).filter(p3.or(p4)).forEach(System.out::println);

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

5
6
7
8
**********
6
9

这是输出。

否定谓词

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

com/zetcode/JavaPredicateNegate.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()方法的用法。

IntPredicate p = n -> n > 5;

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

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

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

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

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

6
7
8
9
12
**********
2
3
1
5

这是示例的输出。

Java 谓词作为方法参数

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

com/zetcode/PredicateMethodParam.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 教程Java 中的HashMap迭代Java ArrayList教程Java HashSet教程Java static关键字Java8 forEach教程读取 Java 中的文本文件读取和写入 Java 中的 ICO 图像

列出所有 Java 教程



回到顶部