1.lambda表示式初體驗
阿新 • • 發佈:2022-05-26
lambda表示式是一個匿名函式,我們可以將lambda表示式理解為一段可以傳遞的程式碼(將程式碼像資料一樣傳遞) 可以寫出更為簡潔的程式碼 場景描述: 建立一個物件集合,刪選出符合要求的物件(1.刪選出工資大於8000的 2.刪除出年齡大於18的) 物件集合如下: List<Employee> employees = Arrays.asList( new Employee("吳孟達", 18, 18000.0), new Employee("劉丹", 19, 10000.0), new Employee("趙四", 20, 5000.0), new Employee("王五", 25, 7000.0), new Employee("李六", 30, 8000.0) ); 1.第一種方式(如果按照正常處理方法,會給每個篩選都建立一個方法,但是如果刪選條件發生變化,就得建立一個新的方法,會造成方法的冗餘 ) 示例程式碼如下: /** * 定義一個根據工資篩選員工的方法 * @param employees:員工列表 * @return 刪選後的員工 */ public List<Employee> employeesFilterBySalary(List<Employee> employees){ List<Employee> employeeList=new ArrayList<>(); for (Employee employee : employees) { if (employee.getSalary()>8000) employeeList.add(employee); } return employeeList; } /* 測試普通刪選方式 */ @Test public void testEmployeeFilterBySalary(){ List<Employee> employeeList = employeesFilterBySalary(employees); for (Employee employee : employeeList) { System.out.println(employee); } } 如果更改了工資要大於6000時,得重新寫個方法,這樣雖然可以達到目的,但是造成了程式碼的冗餘 2.第二種方式:採用一種設計模式,叫做策略模式,值得推薦 2.1 先定義一個介面 /* 定義一個藉口並設定泛型以傳入到方法中 定義的方法返回boolean值,該方法進行過濾,有不同的實現類實現該介面,從而達到不同的篩選效果 */ public interface EmployeeFilter<T> { public boolean employeeFilter(T t); } 2.2 介面實現類1(根據工資進行刪選:對於傳入的員工物件,如果工資大於8000,返回true) public class EmployeeFilterBySalary implements EmployeeFilter<Employee> { @Override public boolean employeeFilter(Employee employee) { return employee.getSalary() > 8000 ? true : false; } } 2.3 介面實現類2(根據年齡進行篩選) public class EmployeeFilterByAge implements EmployeeFilter<Employee> { @Override public boolean employeeFilter(Employee employee) { return employee.getAge() > 18 ? true : false; } } 2.4 定義統一的篩選方法 /* 進行員工刪選 */ 重點1:傳入員工列表,刪選策略的介面(重要) public List<Employee> employeesFilter(List<Employee> list, EmployeeFilter<Employee> employeeFilter) { List<Employee> employeeList = new ArrayList<>(); for (Employee employee : list) { if (employeeFilter.employeeFilter(employee)) employeeList.add(employee); } return employeeList; } 2.5 測試 /** * 改造1:使用策略模式進行改造 */ @Test public void test01() { System.out.println("刪選出工資大於8000的"); 1.重點1:傳入不同的介面實現類,即傳入不同的篩選策略,達到不同的篩選效果 List<Employee> employeeListFileterBySalary = employeesFilter(employees, new EmployeeFilterBySalary()); for (Employee employee : employeeListFileterBySalary) { System.out.println(employee); } System.out.println("-------------------------"); 2.重點2:傳入不同的介面實現類,即傳入不同的篩選策略,達到不同的篩選效果 System.out.println("刪選出年齡大於18的"); List<Employee> employeeListFilterByAge = employeesFilter(employees, new EmployeeFilterByAge()); for (Employee employee : employeeListFilterByAge) { System.out.println(employee); } }
改造2:使用匿名內部類的形式:不需要定義介面實現類,而是在建立介面例項時直接重寫介面的方法 /* 進行員工刪選 */ public List<Employee> employeesFilter(List<Employee> list, EmployeeFilter<Employee> employeeFilter) { List<Employee> employeeList = new ArrayList<>(); for (Employee employee : list) { if (employeeFilter.employeeFilter(employee)) employeeList.add(employee); } return employeeList; } /* 使用匿名內部類 */ @Test public void test02() { System.out.println("測試匿名內部類"); 重點1:建立介面例項,直接實現介面中的方法 List<Employee> employeeList = employeesFilter(employees, new EmployeeFilter<Employee>() { @Override public boolean employeeFilter(Employee employee) { return employee.getSalary() > 8000 ? true : false; } }); for (Employee employee : employeeList) { System.out.println(employee); } } 3.改造3:使用lambda表示式: /* 進行員工刪選 */ 重點1:此處傳參使用了泛型 ,這也是下面能使用(e) 的原因 public List<Employee> employeesFilter(List<Employee> list, EmployeeFilter<Employee> employeeFilter) { List<Employee> employeeList = new ArrayList<>(); for (Employee employee : list) { if (employeeFilter.employeeFilter(employee)) employeeList.add(employee); } return employeeList; } /* 優化3:使用lambda表示式 */ @Test public void testLambda() { System.out.println("刪選出年齡大於18的"); List<Employee> employeeListFilterByAge = employeesFilter(employees, (e) -> e.getAge() > 18); employeeListFilterByAge.forEach(System.out::println); System.out.println("-------------------------"); System.out.println("刪選出工資大於8000的"); List<Employee> employeeListFilterBySalary = employeesFilter(employees, (e) -> e.getSalary() > 8000.0); employeeListFilterBySalary.forEach(System.out::println); } 4.使用Strem流: /* 優化方法4:使用Stream流:發現其不需要實現介面,定義公共的篩選方法,直接像操作資料庫一樣直接進行篩選輸出,nb */ @Test public void testByStream() { employees.stream() .filter((e) -> e.getSalary() > 8000) .forEach(System.out::println); }