【java】Lambda表达式详解
·
Java 中的 Lambda 表达式详解:从语法糖到函数式编程
如果你还在写这样的代码:
Collections.sort(list, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o1.length() - o2.length();
}
});
那么你可能已经落后于 Java 8 时代。
使用 Lambda 之后:
list.sort((a, b) -> a.length() - b.length());
代码不仅更简洁,而且表达力更强。
那么问题来了:
- Lambda 到底是什么?
- 为什么只能用于函数式接口?
- Lambda 和匿名内部类有什么区别?
- 它的底层原理是什么?
- 什么时候应该用,什么时候不该用?
这篇文章带你系统掌握 Java Lambda。
一、什么是 Lambda 表达式?
Lambda 表达式是 Java 8 引入的函数式编程特性。
它的本质是:
用更简洁的语法来表示一个“函数式接口”的实现。
二、为什么会有 Lambda?
在 Java 8 之前,如果我们想传递“行为”,只能:
- 使用匿名内部类
- 写很多模板代码
例如:
Runnable r = new Runnable() {
@Override
public void run() {
System.out.println("Hello");
}
};
使用 Lambda:
Runnable r = () -> System.out.println("Hello");
简洁程度完全不同。
三、Lambda 的基本语法
基本结构:
(parameters) -> expression
或:
(parameters) -> { statements }
1️⃣ 无参数
() -> System.out.println("Hello")
2️⃣ 单参数(可省略括号)
x -> x * 2
3️⃣ 多参数
(a, b) -> a + b
4️⃣ 带代码块
(a, b) -> {
int result = a + b;
return result;
}
⚠️ 有大括号必须写 return。
四、函数式接口(Lambda 的前提)
Lambda 只能用于:
只有一个抽象方法的接口
称为:函数式接口
示例
@FunctionalInterface
interface MyFunction {
int add(int a, int b);
}
使用 Lambda:
MyFunction f = (a, b) -> a + b;
常见函数式接口
Java 8 提供了很多现成接口:
1️⃣ Runnable
() -> System.out.println("run")
2️⃣ Comparator
(a, b) -> a.length() - b.length()
3️⃣ Consumer
x -> System.out.println(x)
4️⃣ Supplier
() -> "hello"
5️⃣ Function<T, R>
x -> x.length()
6️⃣ Predicate
x -> x > 10
五、Lambda 的典型使用场景
场景 1:集合排序
list.sort((a, b) -> a.compareTo(b));
场景 2:遍历集合
list.forEach(x -> System.out.println(x));
场景 3:Stream 流操作
list.stream()
.filter(x -> x > 5)
.map(x -> x * 2)
.forEach(System.out::println);
场景 4:线程创建
new Thread(() -> System.out.println("Thread running")).start();
六、方法引用(Lambda 的进阶写法)
当 Lambda 只是调用一个方法时,可以简化:
x -> System.out.println(x);
可以写成:
System.out::println
常见形式:
| 类型 | 示例 |
|---|---|
| 静态方法 | Class::staticMethod |
| 实例方法 | object::method |
| 构造方法 | Class::new |
示例:
list.forEach(System.out::println);
七、Lambda 与匿名内部类的区别
| 对比 | Lambda | 匿名内部类 |
|---|---|---|
| 语法 | 简洁 | 冗长 |
| this 指向 | 外部类 | 当前匿名类 |
| 是否生成 class 文件 | 否(动态生成) | 是 |
| 性能 | 更优 | 稍慢 |
八、Lambda 底层原理
很多人以为 Lambda 是语法糖。
实际上:
Java 使用 invokedynamic 指令 + LambdaMetafactory 实现。
特点:
- 不会生成额外 class 文件
- 运行时动态创建函数对象
- 性能优于匿名内部类
九、易错点总结
❌ 1. 不是所有接口都能用 Lambda
必须是:
@FunctionalInterface
❌ 2. 变量必须是“有效 final”
int x = 10;
list.forEach(i -> System.out.println(x));
如果修改 x 会报错。
❌ 3. Lambda 不适合复杂逻辑
如果代码超过 5-6 行:
建议写成普通方法。
❌ 4. 可读性问题
过度嵌套:
list.stream().filter(...).map(...).flatMap(...).collect(...)
维护困难。
十、Lambda 的优势
- 代码简洁
- 提高可读性
- 支持函数式编程
- 与 Stream 深度结合
- 支持并行计算
十一、什么时候不建议用 Lambda?
- 复杂业务逻辑
- 需要多步异常处理
- 代码可读性下降时
- 调试困难场景
十二、总结
Lambda 的本质是:
让“行为”成为一等公民。
它的价值不仅在于:
- 少写代码
更在于:
- 推动 Java 进入函数式编程时代
- 与 Stream API 深度结合
- 提升并发与集合处理能力
真正掌握 Lambda,你需要理解:
- 函数式接口
- 方法引用
- Stream 操作
- invokedynamic 原理
- 变量捕获机制
更多推荐


所有评论(0)