函数式编程通常用于实现事件侦听器。Java 中的事件侦听器通常被定义为带有单个方法的 Java 接口。下面是一个虚构的单方法接口示例:
public interface StateChangeListener { public void onStateChange(State oldState, State newState); }
这个 Java 接口定义了一个方法,每当状态发生变化时(无论观察的是什么),onStateChange() 方法就会被调用。
在 Java 7 中,您必须实现该接口才能监听状态变化。想象一下,你有一个名为 StateOwner 的类,它可以注册状态事件监听器。下面是一个示例:
public class StateOwner { public void addStateListener(StateChangeListener listener) { ... } }
在 Java 7 中,您可以使用匿名接口实现添加事件监听器,如下所示:
StateOwner stateOwner = new StateOwner(); stateOwner.addStateListener(new StateChangeListener() { public void onStateChange(State oldState, State newState) { // do something with the old and new state. } });
首先创建一个 StateOwner 实例。然后在 StateOwner 实例上添加一个 StateChangeListener 接口的匿名实现作为监听器。
在 Java 8 中,您可以使用 Java lambda 表达式添加事件监听器,如下所示:
StateOwner stateOwner = new StateOwner(); stateOwner.addStateListener( (oldState, newState) -> System.out.println("State changed") );
lambda 表达式就是这一部分:
(oldState, newState) -> System.out.println("State changed")
lambda 表达式与 addStateListener() 方法参数的参数类型相匹配。如果 lambda 表达式与参数类型(本例中为 StateChangeListener 接口)相匹配,则 lambda 表达式将被转换为实现与该参数相同接口的函数。
Java lambda 表达式只能用于与之匹配的类型是单一方法接口的情况。在上面的示例中,一个 lambda 表达式被用作参数,参数类型是 StateChangeListener 接口。该接口只有一个方法。因此,lambda 表达式与该接口成功匹配。
单一方法接口有时也被称为功能接口。将 Java lambda 表达式与功能接口相匹配分为以下几个步骤:
接口是否只有一个抽象(未实现)方法?
lambda 表达式的参数是否与单个方法的参数相匹配?
lambda 表达式的返回类型是否与单一方法的返回类型一致?
如果这三个问题的答案都是肯定的,那么给定的 lambda 表达式就与接口成功匹配了。