您好,我是湘王,这是我的51CTO博客,欢迎您来,欢迎您再来~
Java在其技术发展周期中经历过几次比较重要的变化,如果不是这几次比较重要的变化,恐怕不会有现在这样的江湖地位。个人看来,至少有两次,一是2010~2011年兴起的移动应用开发,Android的出现,让Java狠狠地出了次风头。再就是2014年发布的Java8,这个版本也是Java8之前和后续所有版本的一个分水岭。尽管在Java8之后出现了更多的版本,也加入了很多的功能,但从改变上来上,Java8可以说是一次脱胎换骨的变化,而原因就在于它引入了函数式编程(这个没有绝对的正确与否,仅是个人之间)。
Java码农都知道,虽然都学过集合、I/O、多线程、泛型、抽象类、注解、反射等若干高大上的内容,但实际上真正在工作中最头疼、用得最多的却是集合操作。这也很好理解:业务数据就是业务的血肉,而对数据的读取、存储、传输等操作,会业务规则变得非常麻烦。
比如像单纯数字列表的筛选、排序、去重,对于JDK7及以下版本来说会比较麻烦,类似[1, 3, 7, 2, 10, 13, 11, 9, 22]这样的列表,即使是比较简单的冒泡排序,也至少需要一个嵌套循环。
再就是含有复杂嵌套对象的列表,其查询、排序、筛选等需求,如果使用目前的Java集合类库,实现起来会异常麻烦,例如,假如现在需要实现让不同公司的员工举行联谊,将信息登记在一个列表上,然后选出未婚员工,解决员工单身问题,且将全部的员工按年龄从小到大排序,如果要你来实现,该怎么做?这其实就是一个列表数据筛选的问题,List<Company<Employee>>这样的集合数据进行排序、汇总等操作,会非常麻烦。
也就是假如有下面的类和对象:
那么,当要实现某宝、某东和某哈哈的员工联谊并解决单身问题时,就会比较麻烦,就像这样:
这种方式就完全是一种面向过程的编程,号称纯面向对象设计、编程的Java,在解决这种问题时就是一个讽刺!
既然有了问题,肯定要正视并解决,但解决的方法不在于怎么改进这种代码(大师们的思路往往清奇,但管用)。
在Java还在使用Swing做一些小组件的时候(Swing虽然已经完全被主流应用淘汰了,但代码还保留在Java中),大师们就注意到了一个现象:
可以看到,红色部分的代码几乎没有差别,除了一点内容之外,代码几乎99%都是一样的。而且,类似于
这种代码块,在Java中随处可见。而这种代码块,本质上是由actionListener变量「保存」的。所以,这一过程类就似于「将代码赋值给变量」。
再于是,「优化」过程开始了:
1、因为ActionListener是以匿名类的方式实现的,既然它都已经不想让人知道自己干了什么,退出江湖了,又何必再露脸呢?
2、因为button的addActionListener里面已经要求了ActionListener作为参数,所以其实只要是个稍微聪明点的编译器,它自己就应该能够推断出来需要什么,不用我再来告诉它一次,有点多此一举了;
3、第三点就是,其实咱们写代码,最终是只需要两个东西的,也就是数据和结果,而且这个类本身也是匿名的,所以它完全可以去掉,去掉以后应该是这样的:
接下来,public是多余的,因为只是作为参数了,有没有public没啥区别,所以去掉;然后void也是多余的,编译器可以推断出来有没有返回值,以及它的返回值是啥;然后方法名actionPerformed也是多余的,因为这段代码已经被赋值给「代码块」了,所以它不需要,也不配拥有自己的名字了,所以结果应该是这样的:
精简成这样了,而且进行到这一步,我想Java8开发组的工程师们已经知道自己在干嘛了。刚开始只是尝试着找到优化的方向,另外说一句,咱们可能用了不到几分钟就做到了这一步,那些工程师们可是呕心沥血了几年才达到了这一步的,所以在这里,我们需要向那些优秀的工程师们致敬,感谢他们为我们这些程序员所做出的付出,为整个Java开发社区和生态所做出的贡献!然后,和返回类型一样,需要什么类型的数据编译器也应该是能够自己推断出来的,所以括号里那个ActionEvent也可以省略了:
而进行到这一步,其实代码已经可以放在一行了,就像这样:
但这样太丑了,我想应该是有些颜值控的工程师最终做了这样的改动:
终于大功告成!所以可以用一张图来回顾一下整个Lambda的诞生过程:
虽然这只是我们现在看到的一小步,但是负责维护Java的工程师们应该是往前走了一大步。这种死磕的精神,才是每个码农、工程师们应该学习的。
感谢您的大驾光临!咨询技术、产品、运营和管理相关问题,请关注后留言。欢迎骚扰,不胜荣幸~