引言
通過前面的系列文章,我們對Java8的新特性都有了一定的瞭解。但我們應該如何在項目中去應用,知道項目中什麼地方可以使用,才能幫助自己有更深一步的瞭解。本篇文章將通過項目中的需求實例,來實踐Lambda表達式。
需求實例
- 篩選公司員工集合中年齡大於35歲的員工
以上需求,我們用最熟悉也是最原始的方法,就是對員工集合進行遍歷,然後符合要求的員工,加入到一個新的集合中返回,代碼如下:
//獲取年齡大於35的員工
public static List<Employee> filterEmployee(List<Employee> list){
List<Employee> employeeList = new ArrayList<>();
for (Employee employee:list) {
if(employee.getAge() > 35){
employeeList.add(employee);
}
}
return employeeList;
}
如果現在需求變了,或者增加一個需求,想要篩選公司員工集合中工資大於5000的員工信息,我們按照以上方式,需要改判斷一行的代碼即可,代碼如下:
- 篩選公司員工集合中工資大於5000的員工信息
//獲取工資大於5000的員工信息
public static List<Employee> filterEmployeeSalary(List<Employee> list){
List<Employee> employeeList = new ArrayList<>();
for (Employee employee:list) {
if(employee.getSalary() > 5000){
employeeList.add(employee);
}
}
return employeeList;
}
實現很簡單,但兩個需求的代碼對比來看,只有一行代碼不同,重複率很高。於是,我們可以想到用設計模式的方法優化。
- 優化方式一:利用策略設計模式,按不同的需求篩選員工信息
//增加一個接口
public interface MyPredicate<T> {
boolean test(T t);
}
//增加按年齡篩選員工的類,並實現上面的接口
public class filterEmployeeByAge implements MyPredicate<Employee> {
@Override
public boolean test(Employee employee) {
return employee.getAge() > 35;
}
}
//篩選員工的方法
public static List<Employee> filterEmployee(List<Employee> list,MyPredicate<Employee> mps){
List<Employee> employeeList = new ArrayList<>();
for (Employee employee : list) {
if(mps.test(employee)){
employeeList.add(employee);
}
}
return employeeList;
}
如果我們需要按年齡篩選員工,只需要使用filterEmployeeByAge即可,代碼如下:
List<Employee> employees2 = filterEmployee(employees,new filterEmployeeByAge());
for (Employee employee : employees2) {
System.out.println(employee);
}
如果我們又需要按薪資篩選員工,則增加一個filterEmployeeBySalary類並實現接口即可,代碼如下:
public class filterEmployeeBySalary implements MyPredicate<Employee> {
@Override
public boolean test(Employee employee) {
return employee.getSalary() > 5000;
}
}
List<Employee> employees3 = filterEmployee(employees,new filterEmployeeBySalary());
for (Employee employee : employees3) {
System.out.println(employee);
}
和之前的方法相比,我們不再需要因爲一個需求的增加而去重複創建方法了,我們篩選員工的方法只需要實現一次。需要按不同的需求篩選員工,新建一個對應的類並且實現接口即可。
但是上述方式,我們需要新增類,並且實現接口,而且每個類的代碼也並不多,也是存在大量的重複,於是有了下面的優化方式。
- 優化方式二:匿名內部類
//優化方式二匿名內部類:篩選工資
List<Employee> employees4 = filterEmployee(employees, new MyPredicate<Employee>() {
@Override
public boolean test(Employee employee) {
return employee.getSalary() <= 5000;
}
});
for (Employee employee : employees4) {
System.out.println(employee);
}
相較於方式一,我們的代碼簡單了,不再需要新增類,也不需要單獨寫實現。
寫到這裏,我們就可以和之前學習的東西很好的銜接上了。Lambda表達式可以進一步幫助我們優化代碼,我們也不再需要使用匿名內部類。
- 優化方式三:Lambda表達式
//優化方式三Lambda表達式:篩選工資
List<Employee> employees5 = filterEmployee(employees,(e) -> e.getSalary()<=3000);
employees5.forEach(System.out::println);
- 優化方式四:Stream API
//優化方式四Stream流操作:篩選工資
employees.stream()
.filter(employee -> employee.getSalary()>3000)
.limit(2)
.forEach(System.out::println);
總結
通過以上需求的實踐,很清楚的引入了Lambda和Stream的相關操作,這也是我們爲什麼要使用Lambda的重要原因。以上代碼示例,可通過github查看:why lambda