lambda 表达式

lambda 表达式的产生来源

// 定制一个比较器根据字符串的长度来排序
class LengthComparator implements Comparator<String> {
    @Override
    public int compare(String o1, String o2) {
        return o1.length() - o2.length();
    }
}
var strings = new String[]{"343rere", "abc", "cdfefef", "a", "adeeefffeerf"};
// Arrays.sort(strings); 默认排序
Arrays.sort(strings, new LengthComparator());

如上所示,我们只是想实现一个自定义的排序方法,但不得不为了它单独定义一个类,并实 现自定义的方法,在使用的时候传递这个类的一个实例。有没有像其他语言那样可以直接传 递一个函数而不用创建对象呢?

我们可以像下面这样构建一个匿名类来简化

var strings = new String[]{"343rere", "abc", "cdfefef", "a", "adeeefffeerf"};
Arrays.sort(strings, new Comparator<String>() {
    @Override
    public int compare(String o1, String o2) {
        return o1.length() - o2.length();
    }
});

进一步简化成如下这样:

(String o1,String o2) -> o1.length() - o2.length());像这种带参数变量的表达式就 叫做 lambda 表达式。 编译器可以自动推导类型,还可以再进一步简化成如下这样:

还可以更进一步简化为方法引用:

函数式接口

只有一个抽象方法的接口(可以有别的方法,但抽象方法只能有一个)称为函数式接口。 上例中的 Comparator 就是一个函数式接口,我们用 lambda 表达式实现了它的 compare 抽象方法。最好把 lambda 表达式看作是一个函数,而不是一个对象,另外要接受 lambda 表达式可以传递到函数式接口,java 并没有为语言增加函数类型,其实像 lambda 表达式 所能做的也只是转换为函数式接口。

java api 在 java.util.function 包中定义了很多非常通用的函数式接口。

方法引用

System.out::println就是一个方法引用,它指示编译器生成一个函数式接口的实例,覆 盖这个接口的抽象方法来调用给定的方法,本质就是上例中第二种方式。

构造器引用

lambda 表达式的变量作用域

lambda 分三个部分:

  1. 参数

  2. 代码块

  3. 自由变量的值,指非参数而且不在代码块中定义的变量

这个自由变量有一个限制:必须是不会改变的变量,也就是说必须是一个事实最终变量。 lambda 表达式中使用 this 时,是指创建这个 lambda 表达式的方法的 this,而不是这个 lambda 表达式。 lambda 表达式就是闭包。

Last updated

Was this helpful?