lambda表达式是Java8的新特性,它的特点是可以让代码更简洁,更易于理解,可以省略掉那些看起来很多余的代码。
我们知道,Java是不能传递方法的,相比于JavaScript可以直接将方法以function类型作为参数在方法间进行传递,Java只能使用对象和基本类型作为参数用来传递。
Java吸取了这个优点,就出现了lambda表达式。但是lambda表达式仍然不能够将方法作为参数进行传递,而是使用类似于内部类的形式,通过传递可执行代码块来达到类似传递方法的目的。
那么我们就进行一次通过策略模式+匿名内部类实现的功能优化成使用lambda表达式的形式的过程吧。
首先,假设我们想要设计一个商城支付的功能:
/** * 由于我们会有很多很多的支付方式,所以我们创建一个总接口,要求所有支付方式都要实现此接口 */ public interface Payment { // 要求所有支付方式重写该方法 void pay(); } /** * 支付的执行类,根据传入的支付方式的对象进行支付操作 */ public class Finance { public void doPay(Payment payment) { payment.pay(); System.out.println("支付完成"); } }
main方法测试:
public class Test { public static void main(String[] args) { // 使用内部类来防止支付方式过多导致类的暴增,过一会儿我们就在这里使用lambda改造优化我们的代码 new Finance().doPay(new Payment() { @Override public void pay() { System.out.println("这里是微信支付"); } }); } }
输出结果:
这里是微信支付 支付完成
ambda优化一下
如果是在Java8以前,这已经算是很好的实现方案了,在Java8下,编译器会提示我们main方法里的这段代码可以优化,也就是使用lambda表达式替换掉内部类的部分,main方法那里可以变成这样:
public class Test { public static void main(String[] args) { // 使用内部类来防止支付方式过多导致类的暴增,过一会儿我们就在这里使用lambda改造优化我们的代码 new Finance().doPay(() -> System.out.println("这里是微信支付")); } }
省略掉了一些没必要写的代码,代码变的更简洁了。
个人简单分析一下这个lambda:
() -> System.out.println("这里是微信支付")
前面一对括号(),保留了参数列表,在里面定义传入所指向箭头的方法(代码块)的参数,例如:
(num1, num2) -> System.out.println("num1:" + num1 + ",num2:" + num2)
如果代码块中要求有多条语句,还可以这样:
(num1, num2) -> { System.out.println("num1:" + num1); System.out.println("num2:" + num2); }
在经过上面的使用lambda表达式优化代码的过程中,我们似乎可以发现一点秘密:
优化前代码:
new Finance().doPay(new Payment() { @Override public void pay() { System.out.println("这里是微信支付"); } });
优化后代码:
new Finance().doPay(() -> System.out.println("这里是微信支付"));
我们会发现,被替换的部分其实就是背景颜色加深的那一部分,而那一部分正好是使用lambda表达式替换掉了匿名类的对象。
所以这里的lambda大致等同于这个类。但其本身只是为了执行其箭头后面的代码块(方法),所以:
所以引用一位大佬的总结:
Lambda表达式,其实是一段可传递的代码。Lambda本质是以类的身份,干方法的活。
最后注明一下lambda表达式的适用情况,并非所有接口都可以lambda表达式进行优化,对应lambda表达式的接口必须只具备唯一的抽象方法,例如本文的 Payment 接口。
如果我们在这个接口中添加了任何其他的方法,lambda表达式都将无法使用。
参考文章:
Lambda 表达式有何用处?如何使用? - bravo1988的回答 - 知乎 https://www.zhihu.com/question/20125256/answer/953750947