Lambda名词释义
Lambda表达式表示匿名函数,和匿名类对比,及不需要声明函数的方法名和返回值,用表达式的形式完成函数的参数和相关逻辑。
Lambda表达式应用于Groovy和Kotlin中,作为实现函数式编程的关键(函数式编程是指一个函数能够作为另一个函数的入参)。而在JDK8中支持了对Lambda表达式的应用。
基本使用
java中对lambda表达式的声明不像Kotlin等,其实质是用一种简单的方式完成一些简单接口的声明和初始化。举例如下:
Runnable runnable1 = new Runnable() {
@Override
public void run() {
System.out.println("Hello");
}
};
new Thread(runnable1).start();
对于启动一个线程并构造Runnable
接口往往需要写这么多代码,而对于Runnable
其实只关心run()
方法的实现。而lambda便是为了解决这种问题,简化之后如下:
// lambda表达式
Runnable runnable = () -> {System.out.println("Hello")};
new Thread(runnable).start();
可以发现其中Runnable
的实现发生了变化,在java中lambda表达式的声明以->
隔开,->
之前声明参数,之后的{}
是方法的逻辑。该表达式就是对run()
的相关声明。因为run()
方法没有参数,所以->
之前用()
表示。而{}
中表示方法逻辑,和普通的方法逻辑一样,如果只有一行,则大括号可以忽略() -> System.out.println("Hello")
。
最后简化如下:
new Thread(() -> System.out.println("Hello")).start();
可以看到只需要一行就可以完成之前的代码逻辑。
lambda表达式的实质是实现接口或抽象类并且完成方法的声明,而对于接口和抽象类要求必须仅有一个待实现的方法(特殊情况后面会提到)。
lambda表达式很容易将其方法体中的逻辑理解成立即运行,其实不是,具体什么时候走,要根据接口中的方法什么时候被调用。
不同用法
lambda需要一个参数
有一个类如下
@FunctionalInterface
public interface Consumer<T> {
void accept(T t);
}
实例该对象的方式如下:
Consumer<String> consumer = (String t) -> System.out.println(t);
Consumer<String> consumer = (t) -> System.out.println(t);
此时lambda就是对accept(T t)
方法的实现。
参数的声明可以省略,因为其实质是实现抽象或接口中的方法,那么参数类型肯定是明确的,而且编译器也能够帮我们检测出。
如上逻辑还有一种写法:
Consumer<String> consumer2 = System.out::println;
该种表示叫做方法引用,以::
作为操作符,后面会分析。
两个参数和返回值
java中比较器Comparator
的类声明如下
@FunctionalInterface
public interface Comparator<T> {
int compare(T o1, T o2);