1、Lambda
Lambda表达式的本质只是一个"语法糖",由编译器推断并帮你转换包装为常规的代码,因此你可以使用更少的代码来实现同样的功能。
这个新特性是为了消除单方法接口实现的匿名内部类,Lambda要求实现的接口中只有一个抽象方法。
在jdk1.8以前的版本中,定义一个Thread是这样的:
1 final int i = 0; 2 new Thread(new Runnable() { 3 @Override 4 public void run() { 5 System.out.println("i = " + i); 6 } 7 }).start();
而Lambda是这样的:
1 int i = 0; 2 new Thread(() -> System.out.println("i = " + i));
2、Lambda起源
在java中可以给变量赋一个“值”,但如果想把”一块代码“赋给变量,应该怎么做呢?
在jdk1.8之前是做不到的,之后利用lambda特性,就可以做到了。
这不是个很简洁的写法,为了使这个赋值操作更加elegant,可以移除一些没用的声明。
这样,就成功并非常优雅的把“一块代码”赋给了一个变量。
“这块代码”,或者说“这个被赋给一个变量的函数”,就是一个Lambda表达式。
但是仍然有一个问题,就是变量aBlockOfCode的类型应该是什么?
在jdk1.8里面,Lambda的类型都是一个接口,而Lambda表达式本身,就是“那段代码”。这是我认为理解Lambda的一个关键所在,简而言之,Lambda表达式本身就是一个接口的实现。
这种只有一个接口函数需要被实现的接口类型,我们叫它“函数式接口”。为了避免后来的人在这个接口中增加接口函数导致其有多个接口函数需要被实现,变成"非函数接口”,我们可以在这个上面加上一个声明@FunctionalInterface, 这样别人就无法在里面添加新的接口函数了:
这样,我们就得到了一个完整的Lambda表达式声明:
如果其中有两个方法则lambda表达式会编译错误,但jdk1.8的新特性允许添加default方法。
3、Lambda语法
(parameters) -> expression 或
(parameters) ->{ statements; }
"->"新的操作符(lambda操作符)
箭头操作符将Lambda表达式拆分成两部分,左侧:Lambda表达式的参数列表,右侧:Lambda表达式中所需执行的功能,即Lambda体。如:
结构很简单,小括号表示参数列表,大括号表示方法体,中间使用一个 "->" 隔开即可。
这里的参数体和方法体分别指的是接口中方法的参数体和方法体。
4、Lambda作用
最直观的作用就是使得代码变得异常简洁。
这两种写法本质上是等价的。但是显然jdk1.8中的写法更加优雅简洁。并且,由于Lambda可以直接赋值给一个变量,我们就可以直接把Lambda作为参数传给函数, 而传统的Java必须有明确的接口实现的定义,初始化才行:
有些情况下,这个接口实现只需要用到一次,传统的jdk1.7必须要求你定义一个“污染环境”的接口实现MyInterfaceImpl,而相较之下,Lambda就显得干净很多。
Ref:
https://www.cnblogs.com/Fndroid/p/6087380.html
https://www.zhihu.com/question/20125256/answer/324121308
http://www.runoob.com/java/java8-lambda-expressions.html