1. 核心前提:什么时候能用?
只有在"函数式接口"作为参数时,才能使用 Lambda 表达式。
什么是函数式接口?
-
定义 :有且仅有一个抽象方法的接口。
-
特征 :通常(但不强制)类上会有
@FunctionalInterface注解。 -
原理 :编译器通过上下文推断,将 Lambda 表达式自动映射到那唯一的一个抽象方法上。
判断标准:
java
// 是函数式接口 (只有一个抽象方法 swimming)
@FunctionalInterface
interface Swim {
void swimming();
}
// 不是函数式接口 (有两个抽象方法)
interface Run {
void fastRun();
void slowRun();
}
2. 语法格式
标准格式:(参数列表) -> { 方法体 }
省略规则(重点)
为了简洁,Java 允许在特定情况下省略语法元素:
-
参数类型:可以不写,编译器自动推断。
(String s) -> ...可简化为(s) -> ...
-
小括号 :如果只有一个参数,小括号可以省略。
(s) -> ...可简化为s -> ...
-
大括号与分号 :如果方法体只有一行代码 ,大括号
{}、分号;和return关键字都可以省略。(x, y) -> { return x + y; }可简化为(x, y) -> x + y
3. 代码解析:
接口定义
java
@FunctionalInterface
interface Swim {
// 唯一的抽象方法:无参数,无返回值
public abstract void swimming();
}
写法对比
写法一:匿名内部类(旧)
编译器看到这里,实际上创建了一个 Swim 的实现对象。
java
methed(new Swim() {
@Override
public void swimming() {
System.out.println("Swiming");
}
});
写法二:Lambda 表达式(新)
编译器发现 methed 接收 Swim 接口,且 Swim 只有一个 swimming() 方法,于是直接把 {} 里的代码填入 swimming() 方法中。
java
// 标准写法
methed(() -> {
System.out.println("Swiming");
});
// 极致简化(因为只有一行代码)
methed(() -> System.out.println("Swiming"));
4. 更多场景举例
根据接口方法的不同(有无参数、有无返回值),Lambda 的写法会有变化。
场景 A:有参数,无返回值
假设接口是:void handle(String msg);
java
// 完整写法
consumer((String msg) -> {
System.out.println("处理消息: " + msg);
});
// 简化写法 (省略类型、小括号、大括号)
consumer(msg -> System.out.println("处理消息: " + msg));
场景 B:有参数,有返回值
假设接口是:int add(int a, int b);
java
// 完整写法
calculator((int a, int b) -> {
return a + b;
});
// 简化写法 (省略类型、大括号、return)
// 注意:如果省略大括号,必须同时省略 return
calculator((a, b) -> a + b);
5. 总结
-
看到方法参数是 接口。
-
检查该接口是否只有一个抽象方法。
-
如果是,直接写
() -> {}。 -
根据参数个数和代码行数,应用省略规则。