目录
Java 8引入了Predicate函数式接口,主要用于表示一个参数的谓词(布尔值函数),在功能上类似于JavaScript-Array的filter()方法。
关于“谓词”解释,百度给出了如下解释:

此处,Predicate接口主要是:结合自身的default默认方法——与and()、或or()、非negate(),static静态方法isEqual(),返回一个Predicate对象;然后通过重写内部的test()抽象方法,返回一个布尔值。

这个布尔值就可以用于表示被描述的对象是否与指定的条件相符合(true),或者不符合(false)。

Predicate接口提供了静态成员方法isEqual(),用于判断两个对象是否相等。一个经典应用场景是:结合Stream流式操作,根据指定元素的值,筛选集合中与之相同的所有元素、计算集合中与之相同的元素个数。
例如:我们想筛选集合Collection
PS:注意TStudent类需要重写equals和hasCode()方法。
- public static void main(String[] args) {
- Collection
collection1 = new ArrayList<>(); - collection1.add(new TStudent(1, "Tom", 3.8));
- collection1.add(new TStudent(2, null, 3.5));
- collection1.add(new TStudent(3, "John", 2.3));
- collection1.add(new TStudent(4, "Mike", null));
- collection1.add(new TStudent(null, "Yoke", 4.5));
- collection1.add(new TStudent(2, null, 3.5));
- collection1.add(new TStudent());
-
- System.out.println("原始集合:");
- collection1.forEach(System.out::println);
-
- TStudent temp = new TStudent(2, null, 3.5);
- Predicate
predicate = Predicate.isEqual(temp); -
- System.out.println("【筛选统计结果】");
-
- //1-获取集合中等于temp的元素
- Stream
tStudentStream = collection1.stream().filter(predicate); - List
collect = tStudentStream.collect(Collectors.toList());//Stream转List - collect.forEach(System.out::println);
-
- //2-统计集合中等于temp的元素个数
- long count = collection1.stream().filter(predicate).count();
- System.out.println("个数:"+count);
-
- }

Predicate
定义规则为:字符串的长度大于5,且包含任意英文字母时,即为通过测试。
示例代码如下,
- //methods
- public static void main(String[] args) {
- //利用Predicate接口判断String字符串是否满足指定规则
- Predicate
predicate = new Predicate() { - @Override
- public boolean test(String s) {
- //判断:[1]长度是否大于5;[2]是否包含英文字母
- return s.length()>5&&s.matches(".*[a-zA-Z].*");
- }
- };
-
- boolean test1 = predicate.test("123a45");
- System.out.println(test1);
- boolean test2 = predicate.test("659748");
- System.out.println(test2);
- }

Predicate
例如,指定规则为:删除Collection
- public static void main(String[] args) {
- //定义集合对象
- Collection collection = new ArrayList();
- collection.add(1);
- collection.add(2);
- collection.add(3);
- collection.add(4);
- collection.add(5);
-
- boolean flag = collection.removeIf(new Predicate() {
- @Override
- public boolean test(Object o) {
- Integer value = Integer.parseInt(o.toString());
- return value % 2 != 0;
- }
- });
-
- System.out.println("flag="+flag);
- collection.forEach(System.out::println);
-
- }

更复杂一点的应用场景,我们可以借助Predicate
- //methods
- public static void main(String[] args) {
- //定义集合对象
- Collection
collection1 = new ArrayList<>(); - collection1.add(new TStudent(1,"Tom",null));
- collection1.add(new TStudent(2,"Linda",null));
- collection1.add(new TStudent(3,"John",2.3));
- collection1.add(new TStudent(4,"Mike",null));
- collection1.add(new TStudent(5,"Yoke",4.5));
- //Predicate
过滤掉绩点成绩为空的学生元素 - boolean flag1 = collection1.removeIf(new Predicate
() { - @Override
- public boolean test(TStudent tStudent) {
- return Objects.isNull(tStudent) || Objects.isNull(tStudent.getGrade());
- }
- });
- System.out.println("flag1="+flag1);
- collection1.forEach(System.out::println);
-
- }

以上示例仅仅是使用了Predicate接口的test()方法。
Predicate接口也提供了三个默认方法and()、or()、negate(),用于执行与或非逻辑判断,但是如何使用呢?
以下,我们创建三个Predicate对象,分别用于判断:
【1】Predicate-1:判断学生成绩是否为空;
【2】Predicate-2:判断学生姓名是否为空;
【3】Predicate-3:判断学生的Id是否为空。
然后我们执行以下几类操作,
【1】过滤掉成绩为空,或者姓名为空、或者id为空的学生;
【2】过滤掉成绩为空,且姓名为空、且id为空的学生;
【3】获取成绩为空,或者姓名为空、或者id为空的学生;
示例代码如下,
- public static void main(String[] args) {
- Collection
collection1 = new ArrayList<>(); - collection1.add(new TStudent(1, "Tom", 3.8));
- collection1.add(new TStudent(2, null, 3.5));
- collection1.add(new TStudent(3, "John", 2.3));
- collection1.add(new TStudent(4, "Mike", null));
- collection1.add(new TStudent(null, "Yoke", 4.5));
-
- System.out.println("过滤前:");
- collection1.forEach(System.out::println);
-
- //Predicate-判断学生id为空
- Predicate
predicate_id = new Predicate() { - @Override
- public boolean test(TStudent tStudent) {
- return Objects.isNull(tStudent)||Objects.isNull(tStudent.getId());
- }
- };
-
- //Predicate-判断学生姓名为空
- Predicate
predicate_name = new Predicate() { - @Override
- public boolean test(TStudent tStudent) {
- return Objects.isNull(tStudent)||Objects.isNull(tStudent.getName());
- }
- };
- //Predicate-判断学生成绩为空
- Predicate
predicate_grade = new Predicate() { - @Override
- public boolean test(TStudent tStudent) {
- return Objects.isNull(tStudent) || Objects.isNull(tStudent.getGrade());
- }
- };
-
- System.out.println("过滤后:");
- //[1] 过滤掉成绩为空,或者姓名为空、或者id为空的学生;
- boolean flag_1 = collection1.removeIf(predicate_id.or(predicate_name).or(predicate_grade));
- collection1.forEach(System.out::println);
-
- }

- public static void main(String[] args) {
- Collection
collection1 = new ArrayList<>(); - collection1.add(new TStudent(1, "Tom", 3.8));
- collection1.add(new TStudent(2, null, 3.5));
- collection1.add(new TStudent(3, "John", 2.3));
- collection1.add(new TStudent(4, "Mike", null));
- collection1.add(new TStudent(null, "Yoke", 4.5));
- collection1.add(new TStudent());
-
- System.out.println("过滤前:");
- collection1.forEach(System.out::println);
-
- //Predicate-判断学生id为空
- Predicate
predicate_id = new Predicate() { - @Override
- public boolean test(TStudent tStudent) {
- return Objects.isNull(tStudent)||Objects.isNull(tStudent.getId());
- }
- };
-
- //Predicate-判断学生姓名为空
- Predicate
predicate_name = new Predicate() { - @Override
- public boolean test(TStudent tStudent) {
- return Objects.isNull(tStudent)||Objects.isNull(tStudent.getName());
- }
- };
- //Predicate-判断学生成绩为空
- Predicate
predicate_grade = new Predicate() { - @Override
- public boolean test(TStudent tStudent) {
- return Objects.isNull(tStudent) || Objects.isNull(tStudent.getGrade());
- }
- };
-
- System.out.println("过滤后:");
- //[2] 过滤掉成绩为空,且姓名为空、且id为空的学生
- boolean flag_2 = collection1.removeIf(predicate_id.and(predicate_name).and(predicate_grade));
-
-
- collection1.forEach(System.out::println);
-
- }

- public static void main(String[] args) {
- Collection
collection1 = new ArrayList<>(); - collection1.add(new TStudent(1, "Tom", 3.8));
- collection1.add(new TStudent(2, null, 3.5));
- collection1.add(new TStudent(3, "John", 2.3));
- collection1.add(new TStudent(4, "Mike", null));
- collection1.add(new TStudent(null, "Yoke", 4.5));
- collection1.add(new TStudent());
-
- System.out.println("过滤前:");
- collection1.forEach(System.out::println);
-
- //Predicate-判断学生id为空
- Predicate
predicate_id = new Predicate() { - @Override
- public boolean test(TStudent tStudent) {
- return Objects.isNull(tStudent)||Objects.isNull(tStudent.getId());
- }
- };
-
- //Predicate-判断学生姓名为空
- Predicate
predicate_name = new Predicate() { - @Override
- public boolean test(TStudent tStudent) {
- return Objects.isNull(tStudent)||Objects.isNull(tStudent.getName());
- }
- };
- //Predicate-判断学生成绩为空
- Predicate
predicate_grade = new Predicate() { - @Override
- public boolean test(TStudent tStudent) {
- return Objects.isNull(tStudent) || Objects.isNull(tStudent.getGrade());
- }
- };
-
- System.out.println("过滤后:");
-
- //[3] 获取成绩为空,或者姓名为空、或者id为空的学生-[即:过滤掉ID、name、grade都不为空的元素]
- boolean flag_3 = collection1.removeIf(predicate_id.negate().and(predicate_name.negate()).and(predicate_grade.negate()));
-
- collection1.forEach(System.out::println);
- }
