一 Lambda体验
2019-04-10 本文已影响0人
败给小萝莉
为什么使用Lambda?回答这个问题之前我们先简单来一段代码。
在Java8之前,我们通常都会使用下面的方式去创建一个匿名内部类:
@Test
public void test1() {
Comparator comparator =new Comparator() {
@Override
public int compare(Integer o1, Integer o2) {
return Integer.compare(o1, o2);
}
};
TreeSet ts =new TreeSet<>(comparator);
}
而有了Lambda表达式以后,我们可以这样写:
@Test
public void test2() {
Comparator<Integer> comparator = (x, y) -> Integer.compare(x, y);
TreeSet<Integer> ts = new TreeSet<>(comparator);
}
简单对比就会发现,使用Lambda表达式让我们写出更简洁、更灵活的代码。也许你觉得还不够爽,那来看一个案例:
我们创建一个集合,存储一些代表公司员工信息的数据:
List<Employee> employees = Arrays.asList(
new Employee("张三", 18, 9999.99),
new Employee("李四", 38, 5555.99),
new Employee("王五", 50, 6666.66),
new Employee("赵六", 16, 3333.33),
new Employee("田七", 8, 7777.77)
);
现在有一个需求,获取公司中员工年龄大于等于35岁的员工信息,你可能会抽取一个方法来过滤员工信息:
public List<Employee> filterEmployeesAge(List<Employee> list) {
List<Employee> emps = new ArrayList<>();
for (Employee e : list) {
if (e.getAge() >= 35) {
emps.add(e);
}
}
return emps;
}
这时候如果又来了一个需求:获取员工工资大于等于5000的员工的信息,那你可能又要抽取一个方法:
public List<Employee> filterEmployeesSalary(List<Employee> list) {
List<Employee> emps = new ArrayList<>();
for (Employee e : list) {
if (e.getSalary() >= 5000) {
emps.add(e);
}
}
return emps;
}
如果还有更多的需求呢?那是不是要重复的更改这段代码?你可能会想到用策略模式来修改这种需求:
创建一个接口,接口中定义一个抽象方法,子类按各自的需求处理自己的业务:
public interface MyPredicate<T> {
boolean deal(T t);
}
处理员工年龄大于等于35岁的业务类:
public class FilterEmployeeByAge implements MyPredicate<Employee>{
@Override
public boolean deal(Employee employee) {
return employee.getAge() >= 35;
}
}
处理员工工资大于等于5000的业务类:
public class FilterEmployeeBySalary implements MyPredicate<Employee> {
@Override
public boolean deal(Employee employee) {
return employee.getSalary() >= 5000;
}
}
封装一个方法,将数据源和业务接口作为参数:
public List<Employee> filterEmplyee(List<Employee> list, MyPredicate<Employee> mp){
List<Employee> emps = new ArrayList<>();
for (Employee employee: list) {
if (mp.deal(employee)) {
emps.add(employee);
}
}
return emps;
}
当我们需要处理具体的业务时就只需要传递对应的数据源和实际的业务处理类对象即可:
@Test
public void test5(){
List<Employee> list = filterEmplyee(employees, new FilterEmployeeByAge());
for (Employee e: list) {
System.out.println(e);
}
}
@Test
public void test6(){
List<Employee> list = filterEmplyee(employees, new FilterEmployeeBySalary());
for (Employee e: list) {
System.out.println(e);
}
}
这样带来的另外一个问题就是需要编写很多的类,还是很麻烦。那看看Lambda表达式是怎么处理的呢?
@Test
public void test9(){
employees.stream()
.filter((e) -> e.getSalary() >= 5000)
.limit(2)//取前两个
.forEach(System.out::println);
//获取所有员工的名字
employees.stream()
.map(Employee::getName)
.forEach(System.out::println);
}
我们没有没有编写业务处理的方法、没有编写业务处理的类,使用Java8中提供的新的API以及Lambda表达式轻松解决了我们上面的问题。你可能对这些语法和操作看的有点陌生,没关系,接下来我们将一个个的介绍这些内容。