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
类; 它具有name
和population
属性。
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
This is the output.
否定谓词
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 谓词。