谈谈Lambda
lambda是JDK1.8之后的一个新特性。在谈lambda之前必须要提到函数式编程,就是只有一个抽象方法的接口。在java中,函数式接口可以作为闭包,用匿名对象的方式重写抽象方法之后作为参数传递。Java中有很多函数式接口,比如Comparator,Runnable接口。lambda必须作用于函数式接口。
下面是jdk源码中关于函数式接口的定义
@FunctionalInterface //检查是否为函数式接口的注解
public interface Comparator<T> {
int compare(T o1, T o2);
此处省略一万个字;
}
我们下面定义了一个下面的测试类,并且要对其进行排序
public class People {
private Integer age;
public People(Integer age) {
this.age = age;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "People{" +
"age=" + age +
'}';
}
}
传统编程习惯下,我们会使用Collections类的sort方法对其进行排序,将一个被排序的集合对象和接口的匿名对象作为参数传进去。如下
public class Test {
public static void main(String[] args) {
List<People> ls = new ArrayList<People>();
ls.add(new People(1003));
ls.add(new People(1007));
ls.add(new People(1002));
ls.add(new People(1004));
Collections.sort(ls, new Comparator<People>() {
@Override
public int compare(People o1, People o2) {
return o1.getAge().compareTo(o2.getAge());
}
});
System.out.println(ls);
}
}
测试结果如下[People{age=1002}, People{age=1003}, People{age=1004}, People{age=1007}]
那么如何利用lambda表达式对代码进行优化呢?
public class Test {
public static void main(String[] args) {
List<People> ls = new ArrayList<People>();
ls.add(new People(1003));
ls.add(new People(1007));
ls.add(new People(1002));
ls.add(new People(1004));
Collections.sort(ls, (People o1,People o2) -> {return o1.getAge().compareTo(o2.getAge());});
System.out.println(ls);
}
测试结果如下[People{age=1002}, People{age=1003}, People{age=1004}, People{age=1007}],
我们发现lambda表达式省略了创建匿名对象的过程,也省略了方法名以及@Override注解。极大的给代码做了个美化。
有了lambda,你就没必要使用传统的匿名对象的方式了,Java8提供了更简洁的语法如下。
Collections.sort(ls, (o1,o2) -> o1.getAge().compareTo(o2.getAge()));
System.out.println(ls);
代码变得更短,更具有可读性。对于函数体只有一行的,可以去掉大括号以及return关键字。
你也可以不用写什么类型,因为java编译器会自动推导出这种类型。
那么问题来了?Lambda表达式仅仅为了简化开发and美化代码吗?恐怕不是。
一个匿名内部类,编译器会为每一个匿名内部类创建相应的类文件。这样就会生成很多的类文件,这个过程就会影响应用的性能。
lambda在效率方面是通过把函数式接口的匿名内部类方法的调用改成类静态方法调用来完成的,提高了性能。
总结lambda简化了通用代码,简少了class文件,提高了效率。真真是极简主义。