Lambda表达式和函数式接口有什么关系?

Java Lambda表达式需要函数式接口(Functional Interface)的支持,两者有密切的关系。
函数式接口是只包含一个抽象方法的接口。当一个接口满足这个条件时,我们就可以使用Lambda表达式来创建该接口的匿名实现。
例如:

@FunctionalInterface 
public interface MathOperation {
    int operate(int a, int b);
}

MathOperation接口只有一个抽象方法operate(),所以它是一个函数式接口。我们可以使用Lambda表达式来创建它的匿名实现:

MathOperation add = (x, y) -> x + y;  

这里,(x, y) -> x + y就是一个Lambda表达式,实现了MathOperation这个函数式接口。

其他例子:

  • Runnable接口:只有一个run()方法,所以是函数式接口。
Runnable runnable = () -> System.out.println("Hello");
  • Comparator接口:只有一个compare()方法,所以也是函数式接口。
Comparator<Integer> comparator = (x, y) -> { ... }; 
  • ActionListener接口:只有一个actionPerformed()方法,所以是函数式接口。
button.addActionListener(event -> { ... }); 

总之,任何只包含一个抽象方法的接口,都可以称为函数式接口,这使得它可以有Lambda表达式来创建匿名实现。Java 8在java.util.function包下定义了许多常用的函数式接口,比如:

  • Consumer
  • Supplier
  • Function
  • Predicate

这使得Lambda表达式可以与这些现成的函数式接口配合使用,极大地简化了代码。