1.Lambda表达式

  Lambda允许把函数作为一个方法的参数(函数作为参数传递进方法中),或者把代码看成数据:函数式程序员对这一概念非常熟悉。(不多赘述,可以参考js的函数式编程)

  语法:

  ( Type1 param1, Type2 param2,.... TypeN paramn ) ->{

    statment1;

    statment2;

    ...

    statmentm;

    return statment(m+1);

  }

  当lambda表达式只包含一条语句时,可以省略大括号、return和语句结尾的分号

  当lambda表达式的参数个数只有一个,可以省略小括号

  例子:

    Arrays.asList("a","b","c").forEach( e -> {

      String a = e;System.out.println(a);

    });

    调用List的foreach方法(该方法会遍历list中的每个元素),其中foreach方法接受一个函数(在这个例子中 该函数的表达形式即为   e -> {  函数体 ;}   其中e为该函数的参数将每个遍历到的元素作为参数传递给函数。

    注意: 例子中 String a=e 是合法的。因为编译器会推断出参数e的类型  当然如果不习惯的话也可以写成 (String e) -> {  String a = e; System.out.println(a); } 这种形式。

 在lambda表达式内部使用外部变量类似于匿名内部类,外部变量必须不可变。  

  例子: 

    String out = "out";//编译器隐式当成final来处理
      Arrays.asList("hello","world").forEach(e -> {
      String inner = "inner";
      System.out.println( out + inner + e );
    });

  另外,在lambda中,this不是指向lambda表达式产生的那个SAM对象,而是声明它的外部对象。

2.方法引用

  语法

    objectName::instanceMethod

    ClassName::staticMethod

    ClassName::instanceMethod

    前两种方式类似,等同于把lambda表达式的参数直接当成instanceMethod|staticMethod的参数来调用。比如System.out::println等同于x->System.out.println(x);Math::max等同于(x, y)->Math.max(x,y)。

    最后一种方式,等同于把lambda表达式的第一个参数当成instanceMethod的目标对象,其他剩余参数当成该方法的参数。比如String::toLowerCase等同于x->x.toLowerCase()。

可以这么理解,前两种是将传入对象当参数执行方法,后一种是调用传入对象的方法。

    构造器引用语法如下:ClassName::new,把lambda表达式的参数当成ClassName构造器的参数 。例如BigDecimal::new等同于x->new BigDecimal(x)。

  3.lambda表达式以及方法引用可以在什么情况下使用?

    java8中新增了函数式接口的概念,。函数式接口就是一个具有一个方法的普通接口(java.lang.Runnable,java.util.concurrent.Callable等),可以被隐式转换为lambda表达式。另外java8中增加了一种特殊的注解@FunctionalInterface能够明确声明接口作为函数式接口的意图。

    例子:    

      @FunctionalInterface
      interface Test2{
        void method();
      }

   该接口的实现可以使用lambda表达式。

  另外 默认方法与静态方法并不影响函数式接口的契约。