Java8(一)--lambda表达式
目录
一、背景:
JDK 8 是 Java 发展史上的里程碑版本,引入了许多革命性特性,极大提升了开发效率和代码可读性。
- Lambda 表达式
- 函数式接口(Functional Interface)
- Stream API
- 方法引用(Method References)
- 接口的默认方法与静态方法
- 新的日期时间 API(java.time)
- Optional 类
- 重复注解(Repeating Annotations)
- 类型注解(Type Annotations)
- 并行数组操作
- CompletableFuture
......
二、什么是lambda表达式:
Lambda 表达式是一种匿名函数(即没有名称的函数),广泛用于支持函数式编程范式的语言(如 Python、Java 8+、C#、JavaScript 等)。
它的核心目的是简化代码,尤其是在需要传递简单函数作为参数的场景中。
1、基础语法:
1. 标准形式
> 有一个参数,无返回值:(参数) -> { 方法体 } 或 参数 -> { 方法体 }
> 有多个参数,有返回值:(参数1, 参数2) -> { return 返回值; }
> 无参数,无返回值:() -> { 方法体 }
2、类型声明可选
Java 编译器可自动推断参数类型:
// 显式声明类型
(int x, int y) -> x + y
// 类型推断
(x, y) -> x * y
三、使用场景:
1、替代匿名内部类:
简化 Runnable、Comparator 等接口的实现:
// 传统匿名内部类
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Running");
}
}).start();
// Lambda 简化
new Thread(() -> System.out.println("Running")).start();
2、集合操作:
结合 Stream API 处理数据:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4);
List<Integer> evenNumbers = numbers.stream()
.filter(n -> n % 2 == 0)
.collect(Collectors.toList());
3、函数式接口:
Lambda 需与函数式接口(仅含一个抽象方法的接口)配合使用:
// 自定义函数式接口
@FunctionalInterface
interface Calculator {
int operate(int a, int b);
}
// 使用 Lambda
Calculator add = (a, b) -> a + b;
System.out.println(add.operate(5, 3)); // 输出 8
四、核心优势:
1、代码简洁性
减少模板代码(如匿名类的 new 和 @Override)。
示例:排序列表的代码对比:
// 传统方式
Collections.sort(list, new Comparator<Integer>() {
@Override
public int compare(Integer a, Integer b) {
return b - a;
}
});
// Lambda 方式
Collections.sort(list, (a, b) -> b - a);
2、函数式编程支持
支持高阶函数(如 map、filter、reduce)。
示例:链式处理集合:
list.stream()
.filter(s -> s.startsWith("A"))
.map(String::toUpperCase)
.forEach(System.out::println);
3. 延迟执行(Lazy Evaluation)
结合 Stream 实现按需计算,优化性能:
Optional<Integer> first = numbers.stream()
.filter(n -> n > 10)
.findFirst();
五、局限性:
1.、仅限函数式接口
无法直接用于非函数式接口(如含多个抽象方法的接口)。
2.、变量捕获限制
Lambda 只能捕获 final 或 effectively final 的外部变量:
int offset = 10;
// 合法:offset 是 effectively final
Function<Integer, Integer> adder = x -> x + offset;
// 非法:修改 offset 后不再是 effectively final
offset = 20;
3、调试困难
匿名特性导致堆栈跟踪中无法显示 Lambda 名称。
六、最佳实践:
1、优先使用方法引用
进一步简化代码(尤其是调用现有方法时):
// Lambda 形式
list.forEach(s -> System.out.println(s));
// 方法引用形式
list.forEach(System.out::println);
2、避免复杂逻辑
若 Lambda 超过 3 行,改用普通方法或匿名内部类。
3、结合泛型增强复用性
定义通用函数式接口:
@FunctionalInterface
interface Transformer<T, R> {
R transform(T input);
}
Transformer<String, Integer> toLength = s -> s.length();

浙公网安备 33010602011771号