Lambda(Java 8+)是简洁的匿名函数,而 函数式接口 是恰好只有 一个抽象方法 的接口——即 lambda 所实现的目标类型。二者结合,将函数式编程带入了 Java,并支撑起了 Stream API。
一个函数式接口
java
{
;
}
只有一个抽象方法的接口是"函数式的"——lambda 可以实现它,因为对于 lambda 究竟代表哪个方法不存在歧义。
// ❌ verbose anonymous class (pre-Java 8)
Calculator add = new Calculator() {
public int calculate(int a, int b) { return a + b; }
};
// ✅ lambda — same thing, far less boilerplate
Calculator add = (a, b) -> a + b;
Calculator multiply = (a, b) -> a * b;
add.calculate(2, 3); // 5
lambda (a, b) -> a + b 提供了那个唯一方法的实现——无需类,无需方法签名样板代码。
Function<String, Integer> length = s -> s.length(); // takes T, returns R
Predicate<Integer> isPositive = n -> n > 0; // takes T, returns boolean
Consumer<String> printer = s -> System.out.println(s); // takes T, returns void
Supplier<String> greeting = () -> "Hello"; // takes nothing, returns T
BiFunction<Integer, Integer, Integer> sum = (a, b) -> a + b; // two args
Java 为常见的形态提供了现成的函数式接口,它们贯穿于整个标准库(尤其是流)。
// when a lambda just calls an existing method, use a method reference
list.forEach(System.out::println); // instead of x -> System.out.println(x)
list.stream().map(String::toUpperCase); // instead of s -> s.toUpperCase()
list.stream().map(Integer::parseInt); // static method ref
// passing behavior as arguments — the core enabler of the Stream API
people.stream()
.filter(p -> p.getAge() > 18) // Predicate lambda
.map(Person::getName) // method reference
.forEach(System.out::println); // Consumer
list.sort((a, b) -> a.compareTo(b)); // Comparator lambda
button.addActionListener(e -> handleClick()); // event handler
Lambda 和函数式接口将函数式编程带入了 Java,从根本上改变了现代 Java 的编写方式。
它们消除了为传递 行为作为数据 而编写的冗长匿名类样板代码,使得简洁的事件处理器、比较器、回调成为可能——最重要的是,整个 Stream API(其 filter/map/reduce 操作都依赖于 lambda)。
理解 lambda 以一个函数式接口(单一抽象方法)为目标、那些内置接口(Function、Predicate、Consumer、Supplier)以及方法引用,对于编写地道的现代 Java 并高效使用流、集合与并发 API 都是必不可少的。
它们代表了语言的一次重大演进,是当下 Java 熟练度的核心所在。