当前位置: 首页 > news >正文

【Java函数篇】Java 8 Predicate函数接口的用法详解

为什么介绍Predicate

自从Java8发布以后,代码里面就多了很多函数式的接口和代码。在流式的编程中,我们经常会用到Predicate和其他函数,在一些开源的代码中也会看到别人定义的Predicate方法。但其实你有没有感觉在写代码的经历中,就很少会定义Predicate方法,都是用在stream流中更多,比如下面这段代码。今天就来学习和分享一下Predicate,彻底了解和掌握Predicate的概念以及用法。
在这里插入图片描述
作为参考,在数学中谓词也通常被理解为布尔值函数“P:X?{true,false}”,成为X的谓词:

// Returns true if number is even; else false.
Predicate<Integer> evenPredicate = n -> n % 2 == 0;    // Returns true if age is greater than or equals to 18; else false.
Predicate<Person> canVote = p -> p.age() >= 18;   //Stream filtering with Predicate
List<Person> voters = personList.stream().filter(canVote).toList();

Predicate函数接口概念

我们先看下Java对Predicate的定义:
表示Predicate是一个接受一个<泛型>参数的布尔函数,返回的是true 或 false,经常被用于数据的过滤:
比如stream.filter(k -> k > 0)
在这里插入图片描述

示例

场景就是过滤一个list,经常会这样写:

    @Testpublic void predicate() {List<People> peopleList = mockPeopleList();peopleList.stream().filter(people -> people.getAge() > 10).forEach(System.out::println);}

其中filter里这个lambda表达是就是个Predicate:

.filter(people -> people.getAge() > 10)

我们换一种写法如下:

    @Testpublic void predicate() {List<People> peopleList = mockPeopleList();Predicate<People> predicate = people -> people.getAge() > 10;peopleList.stream().filter(predicate).forEach(System.out::println);}

这样比较清晰可以看到Predicate的使用方式。

什么时候使用Predicate

其实换种问法就是:在日常编程中,我们可以在哪里使用这些返回 true 或 false 的函数呢?
我们可以使用谓词在对集合中的对象进行条件评估后从集合中筛选对象,评估结果可以是 true 或 false。

例如,我们可以在以下实际用例中使用谓词:

  • 找到特定日期之后出生的所有孩子
  • 特定时间范围内订购的披萨
  • 年龄大于特定岁数的员工
  • 等等……

Predicate用法

1. 简单的Predicate

如前所述,谓词会评估表达式并返回布尔值。现在让我们通过一个简单的示例来看一下创建简单谓词的几个示例。

Predicate<Employee> isAdult = e -> e.getAge() > 18;
Predicate<Employee> isMale = p -> p.getGender().equalsIgnoreCase("M");

2. 复杂的Predicate

我们可以通过混合两个或多个谓词来创建一个复杂的谓词。可以使用and,or,negate等组合

Predicate<Employee> isAdultMale= isAdult.and(isMale);
Predicate<Employee> isAdultOrMale = isAdult.or(isMale);

或者这样:

    @Testpublic void predicate() {List<People> peopleList = mockPeopleList();Predicate<People> ageGrate10 = people -> people.getAge() > 18;Predicate<People> genderMen = people -> people.getSex().equals("男");Predicate<People> levelLess5 = people -> people.getLevel() < 5;peopleList.stream().filter(ageGrate10.and(genderMen).or(levelLess5)).forEach(System.out::println);}

3. 反向谓词

可以使用 negate() 方法创建现有谓词的反向谓词。

Predicate<Employee> isMinor = isAdult.negate();

4. 在Java 8 Stream中使用Predicate

Predicate 是一个函数式接口,可以在需要谓词的任何地方将其传递到 lambda 表达式中。例如,Stream 接口中的 filter() 方法就是这样一种方法。

/*** Returns a stream consisting of the elements of this stream that match the given predicate.*/
Stream<T> filter(Predicate<? super T> predicate);

示例:

Predicate<Employee> isMale = p -> p.getGender().equalsIgnoreCase("M");
List<Employee> maleEmployeeList = employeeList.stream().filter(isMale).toList();

如果我们想使用两个参数来测试一个条件,我们也可以使用 BiPredicate 类。

BiPredicate<Integer, String> isAdultMale = (p1, p2) -> p1 > 18 && p2.equalsIgnoreCase("M");
List<Employee> adultMalesList = employeeList.stream().filter(x -> isAdultMale.test(x.getAge(), x.getGender())).toList();

总结

Predicate 提供了一种定义和使用布尔值条件作为对象的方法,从而使代码更加灵活和富有表现力。


http://www.mrgr.cn/news/53051.html

相关文章:

  • git的使用
  • leaflet(二)画中心点标记和范围
  • pdf怎么压缩的小一点?值得介绍的几种PDF文件压缩的方法
  • 第四届智能电力与系统国际学术会议(ICIPS 2024)
  • 威胁狩猎:基于ELK的日志监控
  • 鸿蒙NEXT开发-应用状态(基于最新api12稳定版)
  • 见证8K场景应用!BOSMA博冠与您相约2024北京安博会
  • 光耦合器固态继电器技术的创新
  • 软件工程(2)软件可靠性与保障措施
  • 【数据结构】宜宾大学-计院-实验四
  • 最好的人工AI智能写作软件排行(详细攻略)!
  • 代码随想录day41:part13
  • ubuntu编译kaldi和vosk
  • 【MATLAB 串口调试+虚拟串口测试】
  • 解决eclipse自动补全代码后会删除后面标黄的代码
  • Flink SQL+Hudi数据入湖与分析实践
  • 法人供应商绩效数据线上化PRD
  • 机械转行网络安全自学经历,零基础学网络安全,血泪总结的干货,零基础入门到精通,收藏这篇就够了
  • 邮件营销标题策略:提升邮件打开率的秘诀?
  • 如何使用代理保护电子邮件?