恕我直言你可能真的不会java第3篇:Stream的Filter与谓词逻辑

一、基础代码准备
建立一个实体类,该实体类有五个属性。下面的代码使用了lombok的注解Data、AllArgsConstructor,这样我们就不用写get、set方法和全参构造函数了。lombok会帮助我们在编译期生成这些模式化的代码。
@Data
@AllArgsConstructor
public class Employee {
private Integer id;
private Integer age; //年龄
private String gender; //性别
private String firstName;
private String lastName;
}
写一个测试类,这个测试类的内容也很简单,新建十个Employee 对象
public class StreamFilterPredicate {
public static void main(String[] args){
Employee e1 = new Employee(1,23,"M","Rick","Beethovan");
Employee e2 = new Employee(2,13,"F","Martina","Hengis");
Employee e3 = new Employee(3,43,"M","Ricky","Martin");
Employee e4 = new Employee(4,26,"M","Jon","Lowman");
Employee e5 = new Employee(5,19,"F","Cristine","Maria");
Employee e6 = new Employee(6,15,"M","David","Feezor");
Employee e7 = new Employee(7,68,"F","Melissa","Roy");
Employee e8 = new Employee(8,79,"M","Alex","Gussin");
Employee e9 = new Employee(9,15,"F","Neetu","Singh");
Employee e10 = new Employee(10,45,"M","Naveen","Jain");
List<Employee> employees = Arrays.asList(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10);
List<Employee> filtered = employees.stream()
.filter(e -> e.getAge() > 70 && e.getGender().equals("M"))
.collect(Collectors.toList());
System.out.println(filtered);
}
}
需要注意的是上面的filter传入了lambda表达式(之前的章节我们已经讲过了),表达过滤年龄大于70并且男性的Employee员工。输出如下:
[Employee(id=8, age=79, gender=M, firstName=Alex, lastName=Gussin)]
二、什么是谓词逻辑?
下面要说我们的重点了,通过之前的章节的讲解,我们已经知道lambda表达式表达的是一个匿名接口函数的实现。那具体到Stream.filter()中,它表达的是什么呢?看下图:可以看出它表达的是一个Predicate接口,在英语中这个单词的意思是:谓词。

什么是谓词?(百度百科)

什么是谓词逻辑?
WHERE 和 AND 限定了主语employee是什么,那么WHERE和AND语句所代表的逻辑就是谓词逻辑
SELECT *
FROM employee
WHERE age > 70
AND gender = 'M'
三、谓词逻辑的复用
通常情况下,filter函数中lambda表达式为一次性使用的谓词逻辑。如果我们的谓词逻辑需要被多处、多场景、多代码中使用,通常将它抽取出来单独定义到它所限定的主语实体中。
比如:将下面的谓词逻辑定义在Employee实体class中。
public static Predicate<Employee> ageGreaterThan70 = x -> x.getAge() >70;
public static Predicate<Employee> genderM = x -> x.getGender().equals("M");
3.1.and语法(并集)
List<Employee> filtered = employees.stream()
.filter(Employee.ageGreaterThan70.and(Employee.genderM))
.collect(Collectors.toList());
输出如下:
[Employee(id=8, age=79, gender=M, firstName=Alex, lastName=Gussin)]
3.2.or语法(交集)
List<Employee> filtered = employees.stream()
.filter(Employee.ageGreaterThan70.or(Employee.genderM))
.collect(Collectors.toList());
输出如下:实际上就是年龄大于70的和所有的男性(由于79的那位也是男性,所以就是所有的男性)
[Employee(id=1, age=23, gender=M, firstName=Rick, lastName=Beethovan), Employee(id=3, age=43, gender=M, firstName=Ricky, lastName=Martin), Employee(id=4, age=26, gender=M, firstName=Jon, lastName=Lowman), Employee(id=6, age=15, gender=M, firstName=David, lastName=Feezor), Employee(id=8, age=79, gender=M, firstName=Alex, lastName=Gussin), Employee(id=10, age=45, gender=M, firstName=Naveen, lastName=Jain)]
3.3.negate语法(取反)
List<Employee> filtered = employees.stream()
.filter(Employee.ageGreaterThan70.or(Employee.genderM).negate())
.collect(Collectors.toList());
输出如下:把上一小节代码的结果取反,实际上就是所有的女性
[Employee(id=2, age=13, gender=F, firstName=Martina, lastName=Hengis), Employee(id=5, age=19, gender=F, firstName=Cristine, lastName=Maria), Employee(id=7, age=68, gender=F, firstName=Melissa, lastName=Roy), Employee(id=9, age=15, gender=F, firstName=Neetu, lastName=Singh)]
欢迎关注我的博客,里面有很多精品合集
- 本文转载注明出处(必须带连接,不能只转文字):字母哥博客。
觉得对您有帮助的话,帮我点赞、分享!您的支持是我不竭的创作动力! 。另外,笔者最近一段时间输出了如下的精品内容,期待您的关注。
- 《手摸手教你学Spring Boot2.0》
- 《Spring Security-JWT-OAuth2一本通》
- 《实战前后端分离RBAC权限管理系统》
- 《实战SpringCloud微服务从青铜到王者》
- 《VUE深入浅出系列》
恕我直言你可能真的不会java第3篇:Stream的Filter与谓词逻辑的更多相关文章
- 恕我直言你可能真的不会java第11篇-Stream API终端操作
一.Java Stream管道数据处理操作 在本号之前写过的文章中,曾经给大家介绍过 Java Stream管道流是用于简化集合类元素处理的java API.在使用的过程中分为三个阶段.在开始本文之前 ...
- 恕我直言你可能真的不会java第9篇-Stream元素的匹配与查找
在我们对数组或者集合类进行操作的时候,经常会遇到这样的需求,比如: 是否包含某一个"匹配规则"的元素 是否所有的元素都符合某一个"匹配规则" 是否所有元素都不符 ...
- 恕我直言你可能真的不会java第6篇:Stream性能差?不要人云亦云
一.粉丝的反馈 问:stream比for循环慢5倍,用这个是为了啥? 答:互联网是一个新闻泛滥的时代,三人成虎,以假乱真的事情时候发生.作为一个技术开发者,要自己去动手去做,不要人云亦云. 的确,这位 ...
- 恕我直言你可能真的不会java第1篇:lambda表达式会用了么?
本文配套教学视频:B站观看地址 在本号之前写过的一些文章中,笔者使用了lambda表达式语法,一些读者反映说代码看不懂.本以为java 13都已经出了,java 8中最重要特性lambda表达式大家应 ...
- 恕我直言你可能真的不会java第2篇:Java Stream API?
一.什么是Java Stream API? Java Stream函数式编程接口最初是在Java 8中引入的,并且与lambda一起成为Java开发的里程碑式的功能特性,它极大的方便了开放人员处理集合 ...
- 恕我直言你可能真的不会java第4篇:Stream管道流Map操作
一.回顾Stream管道流map的基础用法 最简单的需求:将集合中的每一个字符串,全部转换成大写! List<String> alpha = Arrays.asList("Mon ...
- 恕我直言你可能真的不会java第7篇:像使用SQL一样排序集合
在开始之前,我先卖个关子提一个问题:我们现在有一个Employee员工类. @Data @AllArgsConstructor public class Employee { private Inte ...
- 恕我直言你可能真的不会java第8篇-函数式接口
一.函数式接口是什么? 所谓的函数式接口,实际上就是接口里面只能有一个抽象方法的接口.我们上一节用到的Comparator接口就是一个典型的函数式接口,它只有一个抽象方法compare. 只有一个抽象 ...
- 恕我直言你可能真的不会java第12篇-如何使用Stream API对Map类型元素排序
在这篇文章中,您将学习如何使用Java对Map进行排序.前几日有位朋友面试遇到了这个问题,看似很简单的问题,但是如果不仔细研究一下也是很容易让人懵圈的面试题.所以我决定写这样一篇文章.在Java中,有 ...
随机推荐
- vue触发事件的五个关键字
v-on vue中提供了v-on事件绑定 v-on:click='函数'; v-on可以使用@代替 vue 五个触发事件关键字 .stop 用于阻止冒泡 例如 div1 ...
- 前端基础知识之html和css全解
前端回顾 目录 前端回顾 基础知识 HTTP协议 认识HTML HTML组成 HTML标签 div和span标签 特殊的属性 常用标签 认识css 选择器 属性 前端就是展示给用户并且与用户进行交互的 ...
- Beta冲刺 —— 5.31
这个作业属于哪个课程 软件工程 这个作业要求在哪里 Beta冲刺 这个作业的目标 Beta冲刺 作业正文 正文 github链接 项目地址 其他参考文献 无 一.会议内容 1.讨论并解决每个人存在的问 ...
- Rocket - debug - TLDebugModuleInnerAsync
https://mp.weixin.qq.com/s/Xf4VFTHIDFh1NHmfwlTX3w 简单介绍TLDebugModuleInnerAsync的实现. 1. dmInner dmInner ...
- jchdl - GSL实例 - Concat
https://mp.weixin.qq.com/s/oJY6Xj9_oM1gSmvH_dHkJg Concat节点把多根输入线线组合成一排线输出. 参考链接 https://github.c ...
- 前端HTML 定位position 绝对定位 相对定位
>>>position:absolute;绝对定位 当前元素相对于父级元素位置[该父级元素必须也设定了position,不然会继续往上找祖先元素,直到body为止]的定位 >& ...
- 基础数论——EXGCD
1.前言 \(皆さん.こんにちは.\)今天我们来讲 \(EXGCD\) .(扩展欧几里得) 既然是扩展嘛,那肯定有不扩展的,也就是 \(GCD\) . 我们都知道 \(GCD\) 怎么写: ll GC ...
- Window10:不能建立到远程计算机的连接,你可能需要更改此连接的网络设置。
一,右键我的电脑点击管理. 二,在系统工具中找到设备管理,在设备管理中找到网络适配器. 三,在网络适配器中找到WAN Miniport(IP) 四,找到WAN Miniport(IP)右键放心卸载,作 ...
- Java实现蓝桥杯十六进制转八进制
基础练习 十六进制转八进制 时间限制:1.0s 内存限制:512.0MB 提交此题 锦囊1 锦囊2 问题描述 给定n个十六进制正整数,输出它们对应的八进制数. 输入格式 输入的第一行为一个正整数n ( ...
- Java实现 蓝桥杯VIP 算法训练 连续正整数的和
问题描述 78这个数可以表示为连续正整数的和,1+2+3-+12,18+19+20+21,25+26+27. 输入一个正整数 n(<=10000) 输出 m 行(n有m种表示法),每行是两个正整 ...