zoukankan      html  css  js  c++  java
  • 恕我直言你可能真的不会java第3篇:Stream的Filter与谓词逻辑

    file

    一、基础代码准备

    建立一个实体类,该实体类有五个属性。下面的代码使用了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接口,在英语中这个单词的意思是:谓词。
    file

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

    file

    什么是谓词逻辑?

    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)]
    

    欢迎关注我的博客,里面有很多精品合集

    • 本文转载注明出处(必须带连接,不能只转文字):字母哥博客

    觉得对您有帮助的话,帮我点赞、分享!您的支持是我不竭的创作动力! 。另外,笔者最近一段时间输出了如下的精品内容,期待您的关注。

  • 相关阅读:
    Openstack API 开发 快速入门
    virtualBox虚拟机到vmware虚拟机转换
    使用Blogilo 发布博客到cnblogs
    Openstack Troubleshooting
    hdoj 1051 Wooden Sticks(上升子序列个数问题)
    sdut 2430 pillars (dp)
    hdoj 1058 Humble Numbers(dp)
    uva 10815 Andy's First Dictionary(快排、字符串)
    sdut 2317 Homogeneous squares
    hdoj 1025 Constructing Roads In JGShining's Kingdom(最长上升子序列+二分)
  • 原文地址:https://www.cnblogs.com/zimug/p/13155678.html
Copyright © 2011-2022 走看看