初识lambda

  lambda可是是任何函数式接口的实例。当我们把lambda传给任何接受函数式接口类型的参数,这个参数调调用接口中唯一的抽象方法时,就会执行lambda代码块。如果有现成的方法可以实现lambda代码块中的功能,这时就可以使用Java的方法引用。例如Arrays.sort (strings,String::compareToIgnoreCase)。lambda代码块中的this总是指向它所在类的实例

  lambda 表达式有 3个部分:

  1 ) 一个代码块;
  2 ) 参数;
  3 ) 自由变量的值, 这是指的是非lambda参数而且不在代码中定义的变量。

  

lambda 表达式可以捕获外围作用域中变量的值。 在 Java 中, 要确保所捕获的值是明确定义的, 这里有一个重要的限制。在 lambda 表达式中, 只能引用值不会改变的 变量。 例如, 下面的做法是不合法的:

 1     public static void countDown(int start, int delay)
 2     {
 3         ActionListener listener = event ->
 4         {
 5             start-- ; // Error: Variable used in lambda expression should be final or effectively final;
 6             System.out.println(start) ; // Error: Variable used in lambda expression should be final or effectively final;
 7         };
 8         
 9         new Timer(delay, listener).start();
10     }

另外如果在 lambda 表达式中引用变量, 而这个变量可能在外部改变, 这也是不合法的。 例如, 下面就是不合法的:

    public static void countDown(String text, int count)
    {
        for (int i = 1; i <= count; i++) {
            ActionListener listener = event ->
            {
                System.out.println(finalI + ": " + text) ; // Error: Variable used in lambda expression should be final or effectively final;
            };

            new Timer(100, listener).start();
        }

    }

lambda 表达式中捕获的变量必须实际上是最终变量 ( effectivelyfinal 。) 实际上的最终变量是指, 这个变量初始化之后就不会再为它赋新值。 在这里, text 总是指示 同一个 String 对象, 所以捕获这个变量是合法的。不过, i 的值会改变, 因此不能捕获i。

原文地址:https://www.cnblogs.com/fengliang/p/14137580.html