Stream的filter与谓语逻辑

1、什么是谓语逻辑?

如下代码中WHERE 和 AND 限定了主语employee是什么,那么WHERE和AND语句所代表的逻辑就是谓语逻辑。

SELECT *
FROM employee
WHERE age > 70
AND gender = 'M'

lambda表达式表达的是一个匿名接口函数的实现,那具体到Stream.filter()中,它表达的是一个Predicate接口,在英语中这个单词的意思是:谓语。

2、创建一个实体类Employee

下面的代码使用了lombok的注解Data、AllArgsConstructor来代替getter,setter和全参构造方法

    @Data
    @AllArgsConstructor
    public class Employee {
       private Integer id;
       private Integer age;
       /**
       *性别,F女,M男
       */
       private String gender;
       private String firstName;  
       private String lastName;
    }

3、测试

创建十个Employee对象,并筛选出年龄大于70的男性

    public class test{
        
        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);
        }
    }

结果如下:

    [Employee(id=8, age=79, gender=M, firstName=Alex, lastName=Gussin)]

以上代码中filter限制了集合filtered中的内容,所以filter中的语句是谓语,其逻辑就是谓语逻辑。

4、谓语逻辑的复用

通常情况下,filter函数中lambda表达式为一次性使用的谓词逻辑。如果我们的谓词逻辑需要被多处、多场景、多代码中使用,通常将它抽取出来单独定义到它所限定的主语实体中。
比如:将下面的谓词逻辑定义在Employee实体class中。

       /**
       *年龄大于70
       */
       public static Predicate<Employee> ageGreaterThan70 = x -> x.getAge() >70;
      /**
       *性别为男
       */ 
       public static Predicate<Employee> genderM = x -> x.getGender().equals("M");

结果:

     @Data
        @AllArgsConstructor
        public static class Employee {
            private Integer id;
            private Integer age;   //年龄
            private String gender;  //性别
            private String firstName;
            private String lastName;
    	/**
       	*年龄大于70
       	*/
            public static Predicate<Employee> ageGreaterThan70 = x -> x.getAge() >70;
    	/**
       	*性别为男
       	*/ 
            public static Predicate<Employee> genderM = x -> x.getGender().equals("M");
        }
  • 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)]
  • or语法(交集||)
    List<Employee> filtered = employees.stream()
            .filter(Employee.ageGreaterThan70.or(Employee.genderM))
            .collect(Collectors.toList());

结果:

[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)]
  • negate语法(取反)
    List<Employee> filtered = employees.stream()
    	.filter(Employee.ageGreaterThan70
    	.and(Employee.genderM).negate()
    	.collect(Collectors.toList());

结果:

[test.Employee(id=1, age=23, gender=M, firstName=Rick, lastName=Beethovan), test.Employee(id=2, age=13, gender=F, firstName=Martina, lastName=Hengis), test.Employee(id=3, age=43, gender=M, firstName=Ricky, lastName=Martin), test.Employee(id=4, age=26, gender=M, firstName=Jon, lastName=Lowman), test.Employee(id=5, age=19, gender=F, firstName=Cristine, lastName=Maria), test.Employee(id=6, age=15, gender=M, firstName=David, lastName=Feezor), test.Employee(id=7, age=68, gender=F, firstName=Melissa, lastName=Roy), test.Employee(id=9, age=15, gender=F, firstName=Neetu, lastName=Singh), test.Employee(id=10, age=45, gender=M, firstName=Naveen, lastName=Jain)]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

出世&入世

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值