什么是谓语逻辑
如下代码中WHERE 和 AND 限定了主语employee是什么,那么WHERE和AND语句所代表的逻辑就是谓语逻辑。
SELECT *
FROM employee
WHERE age > 70
AND gender = 'M'
lambda表达式表达的是一个匿名接口函数的实现,那具体到Stream.filter()中,它表达的是一个Predicate接口,在英语中这个单词的意思是:谓语。
创建一个实体类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;
}
测试
创建十个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中的语句是谓语,其逻辑就是谓语逻辑。
谓语逻辑的复用
通常情况下,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)]