1. 程式人生 > 其它 >1.lambda表示式初體驗

1.lambda表示式初體驗

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);
    }