在 Java 8 的诸多新特性中,Lambda 表达式无疑是最具革命性的特性之一。它不仅简化了代码编写,更标志着 Java 正式引入函数式编程思想,让开发者能够以更简洁、更优雅的方式处理并发、集合操作等场景。
一、为什么需要 Lambda?
在 Lambda 出现之前,Java 中处理'行为传递'场景(如集合排序、线程创建)时,往往需要编写大量冗余的匿名内部类代码。我们先看一个经典案例:使用 Comparator 对 List 进行排序。
传统匿名内部类方式
List<String> list = Arrays.asList("a", "bb", "ccc");
Collections.sort(list, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o1.length() - o2.length();
}
});
这段代码的核心逻辑是 compare 方法中的'按长度比较',但为了传递这个'行为',我们不得不编写一个完整的匿名内部类——包括接口声明、方法重写等模板代码,显得臃肿且可读性差。
Lambda 表达式优化后
list.sort((s1, s2) -> s1.length() - s2.length());
对比可见,Lambda 表达式直接'提取'了核心逻辑,去掉了所有模板代码,让代码更聚焦于'做什么'而非'怎么写'。这就是 Lambda 的核心价值:简化行为传递,减少冗余代码,提升开发效率。
二、Lambda 核心概念:函数式接口是前提
【1】什么是函数式接口?
函数式接口(Functional Interface)是指:只包含一个抽象方法的接口。它的作用是为 Lambda 表达式提供'目标类型',即 Lambda 表达式本质上是函数式接口中抽象方法的'匿名实现'。
例如,前面案例中用到的 Comparator<String> 接口,就是一个典型的函数式接口——它只包含一个抽象方法 int compare(T o1, T o2)。
【2】如何标识函数式接口?
Java 8 提供了 @FunctionalInterface 注解,用于显式声明一个接口是函数式接口。该注解的作用是:
- 编译期校验:如果接口不符合函数式接口的定义(如包含多个抽象方法),编译器会报错;
- 代码可读性:让其他开发者一眼识别出这是函数式接口。
自定义函数式接口示例:
@FunctionalInterface
public interface MyFunction {
void execute(String msg);
}
注意:函数式接口可以包含默认方法(default 修饰)和静态方法(static 修饰),但只能有一个抽象方法。


