首先,引入一个模拟的项目,公司要求将年龄35岁以上的人员过滤出来。
将人员数据建模,有姓名、年龄、收入:
public class Employee {
private String name;
private int age;
private double salary;
……………………get和Set方法、空参构造器、全参构造器、toString方法…………省略
}
设定一组数据:
List<Employee> employees = Arrays.asList(new Employee("张三", 22, 3000.00),
new Employee("李四", 38, 5000.00),
new Employee("王五", 50, 9000.00),
new Employee("赵六", 33, 6000.00),
new Employee("陈七", 43, 7000.00)
);
用java8之前的方法来完成这个项目:
public List<Employee> filterEmployees(List<Employee> list) {
List<Employee> emps = new ArrayList<>();
for (Employee emp : list) {
if (emp.getAge() >= 35) {
emps.add(emp);
}
}
return emps;
}
public void test01() {
List<Employee> emps = filterEmployees(employees);
for (Employee emp : emps) {
System.out.println(emp);
}
}
将test01()跑起来,将过滤掉小于35岁的人员。
这时,公司需求又变了,还需要过滤掉收入低于5000的所有员工,那么我们需要按照新需求修改上面的程序。
新需求处理代码方式一:使用策略设计模式
建一个接口:
public interface MyFilterEmployee<T> {
public boolean filter(T t);
}
然后为接口写实现类:
首先是按照年龄过滤:
public class FilterEmployeeByAge implements MyFilterEmployee<Employee>{
@Override
public boolean filter(Employee t) {
return t.getAge() >= 35;
}
}
再写一个实现类,按收入过滤:
public class FilterEmployeeBySalary implements MyFilterEmployee<Employee>{
@Override
public boolean filter(Employee t) {
return t.getSalary() > 5000.00;
}
}
在主类里写上过滤方法:
public List<Employee> filterEmployees(List<Employee> list, MyFilterEmployee<Employee> mfe) {
List<Employee> emps = new ArrayList<>();
for (Employee e : list) {
if (mfe.test(e)) {
emps.add(e);
}
}
return emps;
}
实现上面过滤方法:
public void test02() {
List<Employee> emps1 = filterEmployees(employees, new FilterEmployeeByAge());
for (Employee e : emps1) {
System.out.println(e);
}
System.out.println("-------------");
List<Employee> emps2 = filterEmployees(employees, new FilterEmployeeBySalary());
for (Employee e : emps2) {
System.out.println(e);
}
}
显示结果是先是过滤了年龄,然后再-------------之后是过滤了收入。
优化上面使用策略设计模式实现的代码,使用匿名内部类来调用filterEmployees()方法,过滤掉35岁以下的人员:
public void test03() {
List<Employee> emps1 = filterEmployees(employees,new MyFilterEmployee<Employee>() {
@Override
public boolean filter(Employee t) {
return t.getAge() >=35;
}
});
for(Employee e : emps1) {
System.out.println(e);
}
}
直接调用接口类,使用匿名内部类来实现过滤,不再调用接口的2个实现类。
接着用java8的lambda表达式来优化实现代码,过滤掉收入低于5000的人员:
public void test04() {
List<Employee> emps1 = filterEmployees(employees,(e) -> e.getSalary() >= 5000.00);
emps1.forEach(System.out::println);
}
代码简洁明了,而且代码量较上面过滤35岁的,更少。
假设,我们没有filterEmployees()方法,我们可以直接调用Stream API来实现:
public void test05() {
employees.stream().filter((e) -> e.getAge() >= 40)
.forEach(System.out::println);
System.out.println("-------------");
employees.stream().map(Employee::getName)
.forEach(System.out::println);
}
显示结果:在-----------前是过滤掉了40岁以下的人员,在之后是遍历了所有人员的名称。
由上面的例子所示,使用Lambda表达式和StreamAPI,将大大简化代码量,而且阅读起来更加便捷,