一、问题描述
对比 filterEmployeesByAge()方法和 filterEmployeesBySalary 方法后,我们发现,大部分的方法体是相同的,只是 for 循环中对于条件的判断不同。
如果此时我们再来一个需求,查找当前公司中年龄小于或者等于 20 的员工信息,那我们又要创建一个过滤方法了。
看来使用常规方法是真的不方便啊!
1、员工类
@Data
@Builder
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class Employee implements Serializable {
private static final long serialVersionUID = -9079722457749166858L;
private String name;
private Integer age;
private Double salary;
}
2、过滤年龄大于30岁的员工
public List<Employee> filterEmployeesByAge(List<Employee> list){
List<Employee> employees = new ArrayList<>();
for(Employee e : list){
if(e.getAge() >= 30){
employees.add(e);
}
}
return employees;
}
3、过滤工资超过5000的员工
public List<Employee> filterEmployeesBySalary(List<Employee> list){
List<Employee> employees = new ArrayList<>();
for(Employee e : list){
if(e.getSalary() >= 5000){
employees.add(e);
}
}
return employees;
}
二、问题解决
1、 先定义一个泛型接口 MyPredicate,对传递过来的数据进行过滤,符合规则返回 true,不符合规则返回 false。
public interface MyPredicate<T> {
/**
* 对传递过来的T类型的数据进行过滤
* 符合规则返回true,不符合规则返回false
*/
boolean filter(T t);
}
2、接下来,我们创建 MyPredicate 接口的实现类 FilterEmployeeByAge 来过滤年龄大于或者等于 30 的员工信息。
public class FilterEmployeeByAge implements MyPredicate<Employee> {
@Override
public boolean filter(Employee employee) {
return employee.getAge() >= 30;
}
}
3、我们继续获取当前公司中工资大于或者等于 5000 的员工信息,此时,我们只需要创建一个 FilterEmployeeBySalary 类实现 MyPredicate 接口,如下所示:
public class FilterEmployeeBySalary implements MyPredicate<Employee>{
@Override
public boolean filter(Employee employee) {
return employee.getSalary() >= 5000;
}
}
4、定义一个过滤员工信息的方法
//此时传递的参数不仅有员工的信息集合,同时还有一个我们定义的接口实例,在遍历员工集合时将符合过滤条件的员工信息返回
public List<Employee> filterEmployee(List<Employee> list, MyPredicate<Employee> myPredicate){
List<Employee> employees = new ArrayList<>();
for(Employee e : list){
if(myPredicate.filter(e)){
employees.add(e);
}
}
return employees;
}
5、测试
@Test
public void test4(){
List<Employee> employeeList = this.filterEmployee(this.employees, new FilterEmployeeByAge());
for (Employee e : employeeList){
System.out.println(e);
}
}
@Test
public void test5(){
List<Employee> employeeList = this.filterEmployee(this.employees, new FilterEmployeeBySalary());
for (Employee e : employeeList){
System.out.println(e);
}
}
或者使用匿名内部类实现:
@Test
public void test6(){
List<Employee> employeeList = this.filterEmployee(this.employees, new MyPredicate<Employee>() {
@Override
public boolean filter(Employee employee) {
return employee.getAge() >= 30;
}
});
for (Employee e : employeeList){
System.out.println(e);
}
}
@Test
public void test7(){
List<Employee> employeeList = this.filterEmployee(this.employees, new MyPredicate<Employee>() {
@Override
public boolean filter(Employee employee) {
return employee.getSalary() >= 5000;
}
});
for (Employee e : employeeList){
System.out.println(e);
}
}
或者使用Lambda表达式
@Test
public void test8(){
filterEmployee(this.employees, (e) -> e.getAge() >= 30).forEach(System.out::println);
}
@Test
public void test9(){
filterEmployee(this.employees, (e) -> e.getSalary() >= 5000).forEach(System.out::println);
}
再或者使用 Lambda 表达式结合 Stream API,只要给出相应的集合,我们就可以完成对集合的各种过滤并输出结果信息。
@Test
public void test10(){
employees.stream().filter((e) -> e.getSalary() >= 5000).forEach(System.out::println);
}
@Test
public void test11(){
employees.stream().filter((e) -> e.getSalary() >= 5000).limit(2).forEach(System.out::println);
}
@Test
public void test12(){
employees.stream().filter((e) -> e.getSalary() >= 5000).map(Employee::getName).forEach(System.out::println);
}
三、转载自infoq的写作平台文章的说明
7.3万字肝爆Java8新特性,我不信你能看完!(建议收藏)
原文链接: https://xie.infoq.cn/article/0b0da8f001cfe62f49e3c9da5
网友评论