一、Lambda表达式
Lambda 是一个匿名函数,我们可以把 Lambda表达式理解为是一段可以传递的代码(将代码像数据一样进行传递)。可以写出更简洁、更灵活的代码。作为一种更紧凑的代码风格,使Java的语言表达能力得到了提升。
二、由匿名内部函数到Lambda表达式
1、原来的匿名内部函数类
@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表达式
@Test
public void test2(){
Comparator<Integer> com = (x,y) -> Integer.compare(x,y);
TreeSet<Integer> ts=new TreeSet<>(com);
}
三、实例
Lambda使用前后,实现同一功能代码的演变。
员工信息如下:
List<Employee> employees=Arrays.asList(
new Employee("小红",18,9999),
new Employee("小黄",38,7777),
new Employee("小绿",50,5555),
new Employee("小蓝",16,3333),
new Employee("小紫",8,1111)
);
需求:
(1)获取当前公司中员工年龄大于35的员工信息
(2)获取当前公司中员工工资大于5000的员工信息
代码实现:
//需求:获取当前公司中员工年龄大于35的员工信息
@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;
}
//需求:获取当前公司中员工工资大于5000的员工信息
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;
}
通过以上代码我们不难看出,主体代码部分是重复的,每增加一个需求,都需要新增基本相同的代码。
优化一:
采用策略模式,将主体方法抽象出来,每增加一个需求,只需新增一个接口的具体实现(类)。
//优化方式一:策略模式
@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;
}
优化二:
仍然调用接口,新增需求时无需新增类。
//优化方式二:匿名内部类
@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);
}
}
优化三:
无需调用接口,新增需求时,无需新增类
//优化方式三:Lambda表达式
@Test
public void test6(){
List<Employee> list = filterEmployee(employees,(e)->e.getSalary()<=5000);
list.forEach(System.out::println);
}
优化四:
只需员工信息就可实现功能,无需调用其他类或者接口,代码更加简洁、灵活。
//优化方式四:
@Test
public void test7(){
employees.stream()
.filter((e)->e.getSalary()>=5000)
.limit(2)
.forEach(System.out::println);
}
由此,我们可以看出使用Lambda前后,代码的变化过程。