当前位置: 首页 > 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.lryc.cn/news/466331.html

相关文章:

  • C++ 一个反射的例子
  • vue3 解决背景图与窗口留有间隙的问题
  • Cesium for UE-04-一些说明
  • AIGC:开启智能创造的璀璨新篇章
  • 计算机组成原理与系统结构——外部存储器
  • 如何使用 Browserless 抓取动态网站?
  • 第21~22周Java主流框架入门-Spring 2.SpringAOP面向切面编程
  • Flutter不常用组件----InteractiveViewer
  • 【LeetCode HOT 100】详细题解之二分查找篇
  • 管理篇(顶级思维模型(31个))(待做)
  • 十一、数据库配置
  • day02 -- docker
  • ecmascript标准
  • 在Linux命令行中一行执行多个命令
  • u盘快速格式化后怎么恢复文件:深入解析与全面指南
  • 青少年编程能力等级测评CPA C++(二级)试卷(2)
  • aws 把vpc残留删除干净
  • 平衡二叉树最全代码
  • 数据库表的创建
  • 【MySQL 数据库】之--基础知识
  • Flume面试整理-如何处理Flume中的数据丢失
  • 文件处理新纪元:微信小程序的‘快递员’与‘整理师’
  • 应付账款优化,自动化管理5要点
  • Win安装Redis
  • 手把手带你安装U9【win10+sql+U9】,同样适用U9C的安装
  • 若依前后端框架学习——新建模块(图文详解)
  • 【LaTeX和Word版】写论文时如何调整公式和文字的间距
  • 快乐数--双指针
  • 论文阅读-三维结构几何修复(导-4)
  • 数字货币交易所源码开发:场外(OTC)与币币交易所系统的构建指南