Effective Java系列-第42条:Lambda优于匿名类

358 阅读3分钟

大家好,我是骑电动车飙车的小赢同学,一个平平无奇的程序媛。

前言

​ 近期在阅读 《Effective Java》 这本书时,对于本书第 42 条中 写着 Lambda优于匿名类挺好奇,带着对于 Lambda 比匿名类优秀,优秀在哪里的好奇? 提出了以下 3个疑问,我们一起来看看吧。

  • 什么是匿名类

  • 什么是 Lambda

  • Lambda 相对于匿名类的优势在哪里

1.什么是匿名类

1.1 什么是匿名类

匿名类,就是藏在别人身躯下隐式埋名,在某个类的内部,没有名字的类,不需要提供任何的类名可以直接实例化。同时不能被引用,只能创建时用 new 来声明。

1.2 匿名类的实现方式

匿名类主要有两种实现方式:

  • 匿名类继承一个父类

     
    class Person {
      public void eat() {
          System.out.println("父类 eat");
        }
    }
    
    public  class Children {
    
     public void innerclass() {
       //创建匿名类 继承Person类,重写了 eat方法
       Person person = new Person() {
         @Override
         public void eat() {
           System.out.println("我吃饱饱,睡香香");
         }
       };
       person.eat();
     }
    }
    
  • 匿名类实现一个接口

    interface Person {
       public void eat();
     }
    
     public  class Children {
         public void innerclass() {
            //实现接口
             Person person = new Person() {
                 @Override
                 public void eat() {
                     System.out.println("我吃饱饱,睡香香");
                 }
             };
             person.eat();
         }
     }
    

1.3 什么场景下使用匿名类

  • 在 Java 8 之前,当我们想用函数当做方法的参数,只能使用匿名类。创建函数对象的主要方式就是匿名类。

//Comparator是接口,是排序的抽象策略
Collections.sort(words, new Comparator<String>() {
   @Override
   public int compare(String o1, String o2) {
     return Integer.compare(o1.length(),o2.length());
   }
});

从以上匿名类的实现可以看出,我们少创建了一个类,通过匿名对象重写compare方法,通过匿名对象调用,达成了方法一样的效果,这个是匿名类的作用。

匿名内部类没有名字,无法获取类型,只能当超类或者接口类型使用。

2.什么是 Lambda 表达式

Lambda 表达式是 Java8 推出的新特性,允许函数作为参数传入方法中,可以简化代码。使用起来很优雅。

Collections.sort(words,(o1,o2)->Integer.compare(o1.length(),o2.length()));

3.Lambda相对于匿名类的优势在哪些地方

  • 虽然两者都可以简化代码,但是 Lambda 的优势更加明显

     List<String> strList = new ArrayList<>();
         strList.add("aaaa");
         strList.add("bbbb");
         //匿名内部类
         Collections.sort(strList, new Comparator<String>() {
             @Override
             public int compare(String o1, String o2) {
               return Integer.compare(o1.length(),o2.length());
             }
         });
            //lambda表达式
            Collections.sort(strList,(s1,s2)->Integer.compare(s1.length(),s2.length()));
            Collections.sort(strList, Comparator.comparingInt(String::length));
            strList.sort(Comparator.comparingInt(String::length));
    

    从以上可以看出 lambda表达式一行解决,更加简洁。完胜

  • lambda 在某种程度上可以直接取代匿名类,后续写代码的时候尽量用 Lambda。

  • Lambda 是 最小函数对象的最佳方式。从此打开了大家函数式编程的大门

  • 千万不要给函数对象使用匿名类。除非必须要创建非函数接口的实例。

注意 ( 只能使用匿名类,而不能使用 Lambda 的情况 )

  • 创建抽象类的实例,用匿名类。毕竟 Lambda 受限于函数接口
  • 带有多个抽象方法的接口创建实例,可用匿名类
  • 匿名类,this 是指匿名类的实例, Lambda 指向的外部实例。如果需要访问函数对象的内部的主体,就得用匿名类。

总结

Java8 的来临开启了函数式编程的时代,用起来,你才能知道有多香。本篇废话已经够多,但是宗旨只有一个,就是 大胆的使用 Lambda 取代匿名类的写法吧。 当然如果你还在用 Java 8 以前的版本,请忽略我。

再见各位,我只是个废话连篇的孩子。