Lambda基础

黑派客     最近更新时间:2020-01-17 09:50:52

563

在了解Lambda之前,我们先回顾一下Java的方法。

Java的方法分为实例方法,例如Integer定义的equals()方法:

public final class Integer {
    boolean equals(Object o) {
        ...
    }
}

以及静态方法,例如Integer定义的parseInt()方法:

public final class Integer {
    public static int parseInt(String s) {
        ...
    }
}

无论是实例方法,还是静态方法,本质上都相当于过程式语言的函数。例如C函数:

char* strcpy(char* dest, char* src)

只不过Java的实例方法隐含地传入了一个this变量,即实例方法总是有一个隐含参数this

函数式编程(Functional Programming)是把函数作为基本运算单元,函数可以作为变量,可以接收函数,还可以返回函数。历史上研究函数式编程的理论是Lambda演算,所以我们经常把支持函数式编程的编码风格称为Lambda表达式。

Lambda表达式

在Java程序中,我们经常遇到一大堆单方法接口,即一个接口只定义了一个方法:

  • Comparator

  • Runnable

  • Callable

Comparator为例,我们想要调用Arrays.sort()时,可以传入一个Comparator实例,以匿名类方式编写如下:

String[] array = ...
Arrays.sort(array, new Comparator<String>() {    public int compare(String s1, String s2) {        return s1.compareTo(s2);
    }
});

上述写法非常繁琐。从Java 8开始,我们可以用Lambda表达式替换单方法接口。改写上述代码如下:

// Lambda
import java.util.Arrays;

观察Lambda表达式的写法,它只需要写出方法定义:

(s1, s2) -> {    return s1.compareTo(s2);
}

其中,参数是(s1, s2),参数类型可以省略,因为编译器可以自动推断出String类型。-> { ... }表示方法体,所有代码写在内部即可。Lambda表达式没有class定义,因此写法非常简洁。

如果只有一行return xxx的代码,完全可以用更简单的写法:

Arrays.sort(array, (s1, s2) -> s1.compareTo(s2));

返回值的类型也是由编译器自动推断的,这里推断出的返回值是int,因此,只要返回int,编译器就不会报错。

FunctionalInterface

我们把只定义了单方法的接口称之为FunctionalInterface,用注解@FunctionalInterface标记。例如,Callable接口:

@FunctionalInterfacepublic interface Callable<V> {
    V call() throws Exception;
}

再来看Comparator接口:

展开阅读全文