

恕我直言你可能真的不会java第3篇:Stream的Filter与谓词逻辑
source link: http://www.cnblogs.com/zimug/p/13155678.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

一、基础代码准备
建立一个实体类,该实体类有五个属性。下面的代码使用了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)]
欢迎关注我的博客,里面有很多精品合集
- 本文转载注明出处(必须带连接,不能只转文字): 字母哥博客 。
觉得对您有帮助的话,帮我点赞、分享!您的支持是我不竭的创作动力!。另外,笔者最近一段时间输出了如下的精品内容,期待您的关注。
Recommend
-
137
猫:恕我直言,在座的各位都是垃圾。
-
40
-
49
生活 - @powerN - 本来电梯就不大,你推个电动车 /自行车进去还能上几个人?自行车进去还能勉强上 3 个 4 个。电动车连进去都困难,门上都被撞了好几个坑了,还是 TM 要进去,肥一点的电动车一进去就 45°横在哪儿。
-
20
有一次,我在逛 Stack Overflow 的时候,发现有这样一个问题:“Java 中如何产生一个指定范围内的随机数”,我心想,“就这破问题,竟然有 398 万的阅读量,统计确定没搞错?不就一个 Math.random() 的事儿嘛。” ...
-
33
一、回顾Stream管道流map的基础用法 最简单的需求:将集合中的每一个字符串,全部转换成大写! List<String> alpha = Arrays.asList("Monkey", "Lion", "Giraffe", "Lemur"); //不使用Stream管道流 List<...
-
25
一、粉丝的反馈 问:stream比for循环慢5倍,用这个是为了啥? 答:互联网是一个新闻泛滥的时代,三人成...
-
27
在我们对数组或者集合类进行操作的时候,经常会遇到这样的需求,比如: 是否包含某一个“匹配规则”的元素 是否所有的元素都符...
-
6
摘要:性能提升1400+倍,快来看MySQL Volcano模型迭代器的谓词位置优化详解。 本文分享自华为云社区《
-
5
C++ 编译时谓词函数生成 2022.12.09 Netcan
-
1
NSCompoundPredicate 让开发者能够将多个 NSPredicate 对象组合成一个复合谓词。这一机制特别适用于那些需要基于多重判断标准进行数据过滤的场景。然而,在 Swift 重构的新 Foundation 框架中,缺失了与 NSCompoundPredicate...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK