#####1, Lambda expression
Lambda is an anonymous function, and we can think of a Lambda expression as a piece of code that can be passed (passing code like data).You can write simpler, more flexible code.As a more compact code style, Java's language expressiveness has been enhanced.
#####2, from anonymous internal functions to Lambda expressions
1. Original Anonymous Internal Function Class
@Test public void test1(){ Comparator<Integer> com =new Comparator<Integer>(){ @Override public int compare(Integer o1, Integer o2) { return Integer.compare(o1, o2); } }; TreeSet<Integer> ts=new TreeSet<>(com); }
2. Lambda expression
@Test public void test2(){ Comparator<Integer> com = (x,y) -> Integer.compare(x,y); TreeSet<Integer> ts=new TreeSet<>(com); }
#####3. Instance
Lambda is used before and after, to achieve the same function code evolution.
Employee information is as follows:
List<Employee> employees=Arrays.asList( new Employee("Little Red",18,9999), new Employee("Xiaohuang",38,7777), new Employee("Small Green",50,5555), new Employee("Blue",16,3333), new Employee("Small Purple",8,1111) );
Requirements:
(1) Get information about employees older than 35 in the current company
(2) Get information about employees whose wages are more than 5000 in the current company
Code implementation:
//Requirements: Get information about employees older than 35 in the current company @Test public void test3(){ List<Employee> list=filterEmployees(employees); for(Employee employee:list){ System.out.print(employee); } } public List<Employee> filterEmployees(List<Employee> list){ List<Employee> emps=new ArrayList<>(); for(Employee emp :emps){ if(emp.getAge()>=35){ emps.add(emp); } } return emps; } //Requirements: Get information about employees with salaries greater than 5000 in the current company public List<Employee> filterEmployees2(List<Employee> list){ List<Employee> emps=new ArrayList<>(); for(Employee emp :emps){ if(emp.getSalary()>=5000){ emps.add(emp); } } return emps; }
From the above code, it is not difficult to see that the main part of the code is duplicated, and each additional requirement requires the addition of essentially the same code.
Optimize 1:
Using a policy pattern, the principal method is abstracted, and for each additional requirement, only a specific implementation (class) of the interface is added.
//Optimize Mode One: Strategy Mode @Test public void test4(){ List<Employee> list = filterEmployee(employees,new FilterEmployeeByAge()); for(Employee employee:list){ System.out.print(employee); } System.out.println("--------------------------------------------------------"); List<Employee> list2 = filterEmployee(employees,new FilterEmployeeBySalary()); for(Employee employee:list2){ System.out.print(employee); } } public List<Employee> filterEmployee(List<Employee> list,MyPredicate<Employee> mp){ List<Employee> emps=new ArrayList<>(); for(Employee employee:list){ if(mp.test(employee)){ emps.add(employee); } } return emps; }
Optimize two:
Interfaces are still invoked, and no classes need to be added when new requirements are added.
//Optimize Mode 2: Anonymous Internal Class @Test public void test5(){ List<Employee> list = filterEmployee(employees,new MyPredicate<Employee>(){ @Override public boolean test(Employee t){ return t.getSalary()<=5000; } }); for(Employee employee:list){ System.out.println(employee); } }
Optimize three:
No interfaces need to be called, no classes need to be added when new requirements are added
//Optimize mode three: Lambda expression @Test public void test6(){ List<Employee> list = filterEmployee(employees,(e)->e.getSalary()<=5000); list.forEach(System.out::println); }
Optimize 4:
Functionality can be achieved with employee information, without calling other classes or interfaces, and the code is more concise and flexible.
//Optimize mode four: @Test public void test7(){ employees.stream() .filter((e)->e.getSalary()>=5000) .limit(2) .forEach(System.out::println); }
From this, we can see how the code changes before and after using Lambda.