写在前面
关于lambda表达式,网上的资料不少,但是仔细看一看就会发现,写的良莠不齐,且大部分博文的表达较差,词不达意,所以这里自己进行一次总结,方便日后复习。
什么是Lambda表达式?
lambda表达式,是Java作为面向对象的编程语言在函数式编程方面的一些拓展和优点合并。
Lambda 允许把函数(行为)作为一个方法的参数(函数作为参数传递进方法中)。在lambda表达式子出现之前,实现这种功能大部分时候是在依赖匿名内部类。而lambda表达式利用lambda操作符“->”实现了很多以前必须要匿名内部类才能实现的功能,并且极大地简化了代码的结构和复杂度。
lambda操作符将整个lambda表达式分为了两部分,即箭头的左右:
箭头左边表示lambda表达式的参数列表;
箭头右边则具体表示lambda表达式所要执行的功能,或者说是函数体。
这里提前说明,lambda表达式是离不开接口的。见下面这个例子:
多线程大家一定不陌生,创建一个线程无非有两种方法(不考虑线程池):1.继承Thread类;2.实现Runable接口。实际的生产实践中自然是使用第二种方法更多,因为一个类只能有一个父类,但是却可以实现多个接口。那么下面使用第二种方法新建一个线程并且采用匿名内部类的方法实现:
public static void test(){
new Thread(new Runnable(){
@Override
public void run() {
System.out.println("传统匿名内部类的实现方法");
}
}).start();
}
可以看到,代码量还是蛮大的,当然比去实现一个Runable接口要简洁的多得多,如果想进一步简洁代码呢?那就用到了lambda表达式了。
public static void test1(){
new Thread(()-> System.out.println("lambda表达式的实现方法")).start();
}
运行一下:
test();
test1();
//结果如下:
传统匿名内部类的实现方法
lambda表达式的实现方法
可以看到短短一条语句就完全替换了之前的匿名内部类,效率确实有一些高~
通过这个例子,能更好的理解lambda表达式离不开接口。通过上面例子可以大致看出lambda表达式的一些端倪了,让我们来总结一下:
->lambda表达式的左边为形参,注意形参一定要和lambda表达式所关联的接口的抽象方法的形参保持一致,不然会报错!这里很多博文的总结一直有问题,所以重申一下。
->lambda表达式的右边为方法的重写,谁的方法?自然也就是lambda表达式所关联接口的方法的重写,在这里你可以为所欲为的调用其他类的方法进行重写,但是一定要注意返回值务必要和原生的接口方法的返回值一致。针对以上两点,有一句很绕的官方解释:“实现抽象方法的参数列表和返回值类型,必须与方法引用的方法的参数列表和返回值类型保持一致”。建议还是按照我的解释来理解容易一些。
一个例子可能还是太空洞了,请看下面这个例子,让集合list按照我们所制定的规则进行排序:
ArrayList