从jdk的版本迭代来看的话,现在大多少公司使用的还是java8,其中有一部分还在使用java7,甚至式java6,但是从现在来看的话,java已经出到了java12了,那么Lambda作为java8的新特性,那还有没有必要学了,为了弄清楚这个问题,我也在网上查询了相关的资料,最终得到了一些解释
从2019年1月开始,orcale对java8的支持就已经到期了,不会提供免费的updates和security fix了,这就意味着如果你对自己的项目做更高的服务要求的话,就得付费购买orcale的服务了。或者是更新java的版本,升级到jdk9,10,11,12。orcale相比于以前来说,改变了一些策略,会每三年推出一个长期支持的版本,并且免费支持6个月,后续的话就需要付费购买了,这长期支持的版本,分别为,jdk8,11,17,而短期的版本为jdk12,13,14,15,16(这是半年发布的短期版本),那么从技术迭代的过程来看的话,从8到11,以及到17,对于开发者来说的话,还有一个较为长的时间跨度。那么lamdba还是有足够多的时间来使用,所以也值得来学习使用,其实在jdk11中也有在使用lamdba表达式
(题外话,那么对于jdk选择收费这个问题怎么看,首先这个问题,我认为大公司想要orcale的安全维护的话,可能也不会缺这个维护的钱,小公司的话,规模达不到,可以也不需要去购买这个付费)
接下来就进入正题,说一下,lamdba表达式的这个问题:
首先在jdk8之前的话,对于一个java变量来说,我们可以给一个变量赋一个“值”,但是却没法把一个代码片段赋值给一个变量
比如说下面:

想要把一个右边的代码片段赋值给左边的话,这在java 8之前做是做不到的,但是有了java8之后的lamdba就可以解决这个问题了

这样看上去,也还是不够足够的简洁,所以我们需要再来做一些优化:






这样的话,就做到了足够多的优化了,并且是把函数赋值给了变量,这就是一个lamdba表达式
那么这里还有一个问题是,eating这个变量到底是什么类型的?
在java8中所有的lamdba的类型都是一个接口,lamdba本身就是对接口的实现,为了解释这个问题,举个例子:

这种只有一个接口函数需要被实现的接口类型,叫“函数式接口”,为了避免后来的人在这个接口中增加新的接口函数导致有多个接口函数需要被实现,变成“非函数接口”,我们可以在这个接口上添加一个声明@Functionallnterface,这样别人就无法再里面添加新的接口函数了

这样就可以得到一个完整的Lamdba表达式声明

至于说lamdba的作用,对比一下java7和java8的实现就可以看的出来

这两种写法本质上是等价的,但是java8中的却更加的优雅简洁
由于Lamdba可以直接把Lamdba作为参数传给函数,而传统的Java必须有明确的接口实现的定义,初始化才行:

这样的对比之下,Lamdba就要干净很多了
接下来就是Lamdba结合forEach,stream(),method,reference等新特性来让代码变得更加简洁
通过一个例子来说明一下

如果要打印出guiltyPersons List里中的LastName以“Z”开头的人的FirstName
如果是用原生态的Lamdba写法的话,定义两个函数式接口,定义一个静态函数,调用静态函数并给参数赋值Lamdba表达式

这个例子看上去也足够的简洁了,但是还可以更为简洁
首先上述的静态函数中的foreach循环可以做一下优化,可以利用Iterable自带的forEach()来代替

但是其实静态函数只是对list进行了一通操作,所以这里可以甩掉静态函数,直接用stream()的特性来完成

那么这对比最开始的Lamdba表达式的写法,已经非常的简洁了,但是这个时候如果说要println这个人的全部的信息,那么就可以利用Method reference来继续简化,什么式是Method reference,就是用已经写好的Object/Class的method来代替Lamdba expression,格式如下:

那么这基本是上就是Lamdba最简洁的版本了




