美文网首页
lambda 表达式

lambda 表达式

作者: 偶尔也仗义行侠 | 来源:发表于2019-01-26 14:40 被阅读0次
  • 函数式编程
  • 采用简介的语法定义代码块

lambda 表达式是一个可传递的代码块,可以在以后执行一次或多次。

lambda 表达式的语法

--

函数式接口

有且只有一个抽象方法的接口被称为函数式接口(function interface),通常使用@FunctionalInterface注解标记。

对于函数式接口,需要这种接口的对象时,就可以提供一个 lambda 表达式。

最好把 lambda 表达式看作一个函数,而不是一个对象。lambda 表达式可以传递到函数式接口,在调用这个接口的抽象方法的时候会执行 lambda 表达式的体。

如果设计自己的接口,其中只有一个抽象方法,可以用@FunctionalInterface注解来标记这个接口。这样做有两个优点。如果无意中增加了另一个非抽象方法,编译器会产生一个错误消息。另外 javadoc 页里会指出该接口是一个函数式接口。

@FunctionalInterface并不是函数式接口必须使用的注解。依据定义,任何有且只有一个抽象方法的接口都是函数式接口。不过使用@FunctionalInterface注解是一个很好的做法。

方法引用

如果已经有现成的方法可以完成想要传递到其他代码的某个动作,那么可以使用方法引用。

方法引用就是使用::操作符分割方法名与对象或类名,主要有三种情况:

  • object::instanceMethod
  • Class::staticMethod
  • Class::instanceMethod

在前两种情况中,方法引用等价于提供方法参数的 lambda 表达式。例如,System.out::println等价于x -> System.out.println(x)。对于第三种情况,第一个参数会成为方法的目标(实例对象)。例如,String::compareToIgnoreCase等同于(x, y) -> x.compareToIgnoreCase(y)

类似于 lambda 表达式,方法引用也不能独立存在,总是会转换为函数式接口的实例。

构造器引用

构造器引用与方法引用很类似,只不过方法名为new。具体使用哪一个构造器取决于上下文。

变量作用域

lambda 表达式有 3 个部分:

  1. 代码块
  2. 参数
  3. 自由变量的值,这是指非参数而且不在代码块种定义的变量

为了能够使用在 lambda 表达式外定义的变量(自由变量),lambda 表达式的数据结构就必须存储自由变量的值,可以说这个变量被 lambda 表达式捕获(captured)。例如,可以把一个 lambda 表达式转化为包含一个方法的对象,这样自由变量的值就会复制到这个对象的实例变量中。

在 Java 中,lambda 表达式可以捕获外围作用域的值,但要确保所捕获的值是明确定义的。在 lambda 表达式中,只能引用值不会改变的变量,无论这个变量是在 lambda 表达式中改变还是在外部改变,都是不合法的。

lambda 表达式中捕获的变量必须实际上是最终变量。实际上的最终变量是指,这个变量初始化之后就不会再为它赋新值。

在一个 lambda 表达式中使用this关键字时,是指创建这个 lambda 表达式的方法的this参数。

public void Application {
    public void init() {
        ActionListener listener = event -> {
            System.out.println(this.toString());
            ...
        }
    }
}

表达式this.toString()会调用Application对象的toString方法,而不是ActionListener实例的方法。

处理 lambda 表达式

使用 lambda 表达式的重点时延迟执行。毕竟,如果想要立即执行代码,完全可以直接执行,而无需把它包装在一个 lambda 表达式中。之所以希望延迟执行代码,有很多原因,如:

  • 在一个独立的线程中运行代码;
  • 多次运行代码;
  • 在算法的适当位置运行代码(例如,排序中的比较操作);
  • 发生某种情况时执行代码(例如,点击按钮,数据到达,等等);
  • 只在必要时才运行代码。

-- 常用函数式接口

-- 基本类型的函数式接口

相关文章

网友评论

      本文标题:lambda 表达式

      本文链接:https://www.haomeiwen.com/subject/fbqijqtx.html