您好,我是湘王,这是我的CSDN博客,欢迎您来,欢迎您再来~
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
也就是假如有下面的类和对象:
- public class Company
{ - public enum Type { BIG, SMALL };
- private String name;
- private Type type;
- private List
employees; -
- public Company(final String name, final Type type, final List
employees) { - super();
- this.name = name;
- this.type = type;
- this.employees = employees;
- }
-
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public Type getType() {
- return type;
- }
- public void setType(Type type) {
- this.type = type;
- }
- public List
getEmployees() { - return employees;
- }
- public void setEmployees(List
employees) { - this.employees = employees;
- }
- @Override
- public String toString() {
- return this.name;
- }
- }
-
-
-
- public class Employee {
- public enum Type { MANAGER, SELLER, OFFICER };
- private String name;
- private String genger;
- private Integer age;
- private boolean married;
- private Type type;
- public Employee(final String name, final String genger, final Integer age, final boolean married, final Type type) {
- super();
- this.name = name;
- this.genger = genger;
- this.age = age;
- this.married = married;
- this.type = type;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public String getGenger() {
- return genger;
- }
- public void setGenger(String genger) {
- this.genger = genger;
- }
- public Integer getAge() {
- return age;
- }
- public void setAge(Integer age) {
- this.age = age;
- }
- public boolean isMarried() {
- return married;
- }
- public void setMarried(boolean married) {
- this.married = married;
- }
- public Type getType() {
- return type;
- }
- public void setType(Type type) {
- this.type = type;
- }
- @Override
- public String toString() {
- return this.name + "(" + this.genger + ")-" + this.age;
- }
- }
-
-
-
- public static void main(String[] args) {
- // 创造数据
- List
> list = new ArrayList<>(); - List
employees = Arrays.asList( - new Employee("张勇", "男", 28, true, Employee.Type.MANAGER),
- new Employee("李强", "男", 22, false, Employee.Type.SELLER),
- new Employee("王武", "男", 32, false, Employee.Type.SELLER),
- new Employee("梅丽", "女", 26, true, Employee.Type.OFFICER),
- new Employee("郑帅", "男", 29, false, Employee.Type.OFFICER),
- new Employee("曾美", "女", 27, true, Employee.Type.SELLER),
- new Employee("郝俊", "男", 22, true, Employee.Type.SELLER),
- new Employee("方圆", "女", 24, false, Employee.Type.SELLER)
- );
- Company
moubao = new Company("某宝", Company.Type.BIG, employees); -
- employees = Arrays.asList(
- new Employee("吴琼", "女", 27, true, Employee.Type.SELLER),
- new Employee("陈辰", "女", 20, false, Employee.Type.OFFICER),
- new Employee("刘能", "男", 25, true, Employee.Type.OFFICER),
- new Employee("周七", "男", 29, false, Employee.Type.OFFICER),
- new Employee("汪旺", "男", 21, false, Employee.Type.OFFICER),
- new Employee("胡涂", "男", 27, false, Employee.Type.OFFICER),
- new Employee("杨茂", "男", 34, true, Employee.Type.MANAGER),
- new Employee("朱坚", "男", 30, false, Employee.Type.MANAGER)
- );
- Company
mouxin = new Company("某东", Company.Type.BIG, employees); -
- employees = Arrays.asList(
- new Employee("冯过", "男", 35, false, Employee.Type.SELLER),
- new Employee("何花", "女", 27, false, Employee.Type.MANAGER),
- new Employee("卫精", "男", 25, true, Employee.Type.OFFICER),
- new Employee("施工", "男", 28, false, Employee.Type.OFFICER),
- new Employee("沈月", "女", 24, false, Employee.Type.OFFICER),
- new Employee("乐欢", "女", 22, false, Employee.Type.OFFICER),
- new Employee("安全", "男", 33, true, Employee.Type.MANAGER),
- new Employee("林森", "男", 26, true, Employee.Type.SELLER)
- );
- Company
wahaha = new Company("某哈哈", Company.Type.SMALL, employees); - // 加入列表
- list.add(moubao);
- list.add(mouxin);
- list.add(wahaha);
- }
那么,当要实现某宝、某东和某哈哈的员工联谊并解决单身问题时,就会比较麻烦,就像这样:
- /**
- * 方式一:公司联谊未婚员工登记表:传统方法
- */
- List
unMarriedList1 = new ArrayList<>(); - for (Company
company : list) { - if (company.getType() == Company.Type.BIG) {
- List
emps = company.getEmployees(); - // 如果不用Lambda,则必须再次调用排序算法
- for (Employee tempEmployee : emps) {
- if (!tempEmployee.isMarried()) {
- unMarriedList1.add(tempEmployee);
- }
- }
- }
- }
- // 不用Lambda做排序会非常麻烦
- System.out.println("unMarriedList1 -> " + unMarriedList1);
这种方式就完全是一种面向过程的编程,号称纯面向对象设计、编程的Java,在解决这种问题时就是一个讽刺!
既然有了问题,肯定要正视并解决,但解决的方法不在于怎么改进这种代码(大师们的思路往往清奇,但管用)。
在Java还在使用Swing做一些小组件的时候(Swing虽然已经完全被主流应用淘汰了,但代码还保留在Java中),大师们就注意到了一个现象:

可以看到,红色部分的代码几乎没有差别,除了一点内容之外,代码几乎99%都是一样的。而且,类似于

这种代码块,在Java中随处可见。而这种代码块,本质上是由actionListener变量「保存」的。所以,这一过程类就似于「将代码赋值给变量」。
再于是,「优化」过程开始了:

1、因为ActionListener是以匿名类的方式实现的,既然它都已经不想让人知道自己干了什么,退出江湖了,又何必再露脸呢?
2、因为button的addActionListener里面已经要求了ActionListener作为参数,所以其实只要是个稍微聪明点的编译器,它自己就应该能够推断出来需要什么,不用我再来告诉它一次,有点多此一举了;
3、第三点就是,其实咱们写代码,最终是只需要两个东西的,也就是数据和结果,而且这个类本身也是匿名的,所以它完全可以去掉,去掉以后应该是这样的:

接下来,public是多余的,因为只是作为参数了,有没有public没啥区别,所以去掉;然后void也是多余的,编译器可以推断出来有没有返回值,以及它的返回值是啥;然后方法名actionPerformed也是多余的,因为这段代码已经被赋值给「代码块」了,所以它不需要,也不配拥有自己的名字了,所以结果应该是这样的:

精简成这样了,而且进行到这一步,我想Java8开发组的工程师们已经知道自己在干嘛了。刚开始只是尝试着找到优化的方向,另外说一句,咱们可能用了不到几分钟就做到了这一步,那些工程师们可是呕心沥血了几年才达到了这一步的,所以在这里,我们需要向那些优秀的工程师们致敬,感谢他们为我们这些程序员所做出的付出,为整个Java开发社区和生态所做出的贡献!然后,和返回类型一样,需要什么类型的数据编译器也应该是能够自己推断出来的,所以括号里那个ActionEvent也可以省略了:

而进行到这一步,其实代码已经可以放在一行了,就像这样:

但这样太丑了,我想应该是有些颜值控的工程师最终做了这样的改动:

终于大功告成!所以可以用一张图来回顾一下整个Lambda的诞生过程:

虽然这只是我们现在看到的一小步,但是负责维护Java的工程师们应该是往前走了一大步。这种死磕的精神,才是每个码农、工程师们应该学习的。
感谢您的大驾光临!咨询技术、产品、运营和管理相关问题,请关注后留言。欢迎骚扰,不胜荣幸~