Lambda 表达式是 Java 8 中添加的功能。引入 Lambda 表达式的主要目的是为了让 Java 支持函数式编程。 Lambda 表达式是一个可以在不属于任何类的情况下创建的函数,并且可以像对象一样被传递和执行。
Java lambda 表达式用于实现简单的单方法接口,与 Java Streams API 配合进行函数式编程。
在前几篇关于 List、Set 和 Map 的文章中,我们已经看到了这几个 Java 容器很多操作都是通过 Stream 完成的,比如过滤出对象 List 中符合条件的子集时,会使用类似下面的 Stream 操作。
List<A> list = aList.filter(a -> a.getId() > 10).collect(Colletors.toList);
复制代码
其中filter
方法里用到的a -> a.getId() > 10
就是一个 Lambda 表达式,前面几篇文章我们主要策略讲集合框架里那几个常用 Java 容器的使用,对用到 Lambda 的地方知识简单的说了一下,如果你对各种 Stream 操作有疑问,可以先把本篇 Lambda 相关的内容学完,接下来再仔细梳理 Stream 时就会好理解很多了。
本文内容大纲如下:
Lambda 表达式和函数式接口
上面说了 lambda 表达式便于实现只拥有单一方法的接口,同样在 Java 里匿名类也用于快速实现接口,只不过 lambda 相较于匿名类更方便些,在书写的时候连创建类的步骤也免去了,更适合用在函数式编程。
举个例子来说,函数式编程经常用在实现事件 Listener 的时候 。 在 Java 中的事件侦听器通常被定义为具有单个方法的 Java 接口。下面是一个 Listener 接口示例:
public interface StateChangeListener {
public void onStateChange(State oldState, State newState);
}
复制代码
上面这个 Java 接口定义了一个只要被监听对象的状态发生变化,就会调用的 onStateChange 方法(这里不用管监听的是什么,举例而已)。 在 Java 8 版本以前,监听事件变更的程序必须实现此接口才能侦听状态更改。
比如说,有一个名为 StateOwner 的类,它可以注册状态的事件侦听器。
public class StateOwner {
public void addStateListener(StateChangeListener listener) { ... }
}
复制代码
我们可以使用匿名类实现 StateChangeListener 接口,然后为 StateOwner 实例添加侦听器。
StateOwner stateOwner = new StateOwner();
stateOwner.addStateListener(new StateChangeListener() {
public void onStateChange(State oldState, State newState) {
// do something with the old and new state.
System.out.println("State changed")
}
});
复制代码
在 Java 8 引入Lambda 表达式后,我们可以用 Lambda 表达式实现 StateChangeListener 接口会更加方便。现在,把上面例子接口的匿名类实现改为 Lambda 实现,程序会变成这样:
StateOwner stateOwner = new StateOwner();
stateOwner.addStateListener(
(oldState, newState) -> System.out.println("State changed")
);
复制代码
在这里,我们使用的 Lambda 表达式是:
(oldState, newState) -> System.out.println("State changed")
复制代码
这个 lambda 表达式与 StateChangeListener 接口的 onStateChange() 方法的参数列表和返回值类型相匹配。如果一个 lambda 表达式匹配单方法接口中方法的参数列表和返回值(比如本例中的 StateChangeListener 接口的 onStateChange