lambda表达式仅适用于函数式接口(即仅含一个抽象方法的接口),如runnable、comparator、consumer等;多方法接口(如windowadapter)或需定义成员、访问非final变量等场景不可用。

用 Lambda 表达式替换匿名内部类,核心前提是:该类实现的接口必须是函数式接口(即只有一个抽象方法的接口)。只要满足这个条件,语法就能大幅简化。
确认目标接口是否支持 Lambda
Java 中常见的函数式接口有 Runnable、Comparator、Consumer、Function、Supplier 等。如果自己写的接口也只定义了一个抽象方法,并加上了 @FunctionalInterface 注解,它也支持 Lambda。
- 检查接口源码或文档,确认只有 1 个抽象方法(默认方法、静态方法不计)
- 若不确定,IDE(如 IntelliJ 或 Eclipse)通常会在匿名类 new 处提示“Can be replaced with lambda”
基本替换模板:从匿名类到 Lambda
以 Runnable 为例:
传统写法:
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Hello");
}
}).start();
Lambda 写法:
new Thread(() -> System.out.println("Hello")).start();
- 左边
()对应方法参数列表(run()无参,所以为空括号) - 箭头
->是语法分隔符 - 右边是方法体;单条语句可省略花括号和分号
带参数的常见场景(如 Comparator、ActionListener)
排序示例(Comparator):
// 匿名类
list.sort(new Comparator<string>() {
@Override
public int compare(String s1, String s2) {
return s1.length() - s2.length();
}
});
</string>
// Lambda(参数类型自动推导) list.sort((s1, s2) -> s1.length() - s2.length());
- 参数类型通常可省略(编译器能根据上下文推断)
- 若需显式类型,写成
(String s1, String s2) -> ... - 多条语句用花括号包裹,并显式写
return(如->{ System.out.println(...); return 0; })
注意不能替换的情况
以下情形无法直接用 Lambda 替代:
- 接口有多个抽象方法(例如自定义接口里写了
void a(); void b();) - 需要调用匿名类中定义的其他方法或字段(Lambda 本身没有类结构,不支持定义新成员)
- 需要使用
this指向匿名类实例(Lambda 中的this指向外部类实例)
遇到这些情况,要么重构为函数式接口,要么保留匿名类或改用普通私有方法 + 方法引用。










