一、Lambda表达式革命性变革
1. 从匿名类到Lambda的演进
Runnable oldRunnable = new Runnable() {
@Override
public void run() {
System.out.println("Old way");
}
};
Runnable newRunnable = () -> System.out.println("New way");
2. Lambda语法核心要素
结构 |
示例 |
无参 |
() -> System.out.println("Hi") |
单参数(可省略括号) |
s -> s.length() |
多参数 |
(a, b) -> a + b |
代码块 |
(x, y) -> { return x > y; } |
二、函数式接口与四大核心接口
1. 函数式接口定义
@FunctionalInterface
public interface MyFunction<T, R> {
R apply(T t);
default MyFunction<T, R> andThen(MyFunction<R, ?> after) {
return t -> after.apply(apply(t));
}
}
2. Java 8四大核心函数式接口
接口 |
方法签名 |
典型应用场景 |
Function<T,R> |
R apply(T t) |
数据转换 |
Predicate<T> |
boolean test(T t) |
条件过滤 |
Consumer<T> |
void accept(T t) |
遍历消费 |
Supplier<T> |
T get() |
延迟生成对象 |
三、Stream API 流式编程深度解析
1. 流操作三阶段模型
2. 常用操作分类
操作类型 |
特点 |
典型方法 |
中间操作 |
延迟执行 |
filter(), map(), sorted(), distinct() |
终端操作 |
触发实际计算 |
forEach(), collect(), count() |
短路操作 |
提前终止 |
findFirst(), anyMatch(), limit() |
四、Stream API 企业级实战案例
1. 大数据处理:统计部门薪资
Map<String, Double> departmentSalary = employees.stream()
.filter(e -> e.getAge() > 25)
.collect(Collectors.groupingBy(
Employee::getDepartment,
Collectors.averagingDouble(Employee::getSalary)
));
2. 多层嵌套集合处理
List<String> allTags = orders.stream()
.flatMap(order -> order.getItems().stream())
.flatMap(item -> item.getTags().stream())
.distinct()
.toList();
3. 并行流性能优化(谨慎使用)
long count = largeList.parallelStream()
.filter(s -> s.length() > 10)
.count();
五、Lambda与Stream性能关键指标
1. 性能对比测试(单位:毫秒)
操作类型 |
传统循环 |
Stream串行 |
Stream并行(8核) |
10万次过滤 |
5 ms |
8 ms |
12 ms |
100万次映射 |
25 ms |
35 ms |
18 ms |
1000万次归约 |
120 ms |
150 ms |
45 ms |
结论:
- 小数据量优先使用传统循环
- 大数据计算考虑并行流
- 避免在stream中处理I/O操作
六、Lambda陷阱与最佳实践
1. 变量捕获规则
int count = 0;
list.forEach(s -> {
count++;
});
2. 方法引用四大形式
类型 |
示例 |
静态方法 |
String::valueOf |
实例方法 |
System.out::println |
类构造器 |
ArrayList::new |
任意对象实例方法 |
String::length |
3. 调试技巧
List<String> result = list.stream()
.peek(s -> System.out.println("原始值: " + s))
.map(String::toUpperCase)
.peek(s -> System.out.println("转换后: " + s))
.toList();
七、函数式编程进阶:Optional与CompletableFuture
1. Optional空值安全处理
public String getCity(User user) {
return Optional.ofNullable(user)
.map(User::getAddress)
.map(Address::getCity)
.orElse("Unknown");
}
2. CompletableFuture链式调用
CompletableFuture.supplyAsync(() -> queryFromDB())
.thenApplyAsync(data -> processData(data))
.thenAcceptAsync(result -> sendNotification(result))
.exceptionally(ex -> {
log.error("任务失败", ex);
return null;
});
八、跨版本对比(Java 8 vs 11 vs 17)
特性 |
Java 8 |
Java 11 |
Java 17 |
局部变量类型推断 |
无 |
var关键字 |
var增强 |
Stream API增强 |
基础操作 |
takeWhile/dropWhile |
toList()便捷方法 |
函数式接口扩展 |
基础四大接口 |
无 |
无 |
并行流优化 |
ForkJoinPool.commonPool() |
无 |
无 |
九、常见面试题与解决方案
1. 面试题:Stream的map和flatMap区别?
答案:
map
:1:1元素转换
flatMap
:1:N元素展开(处理嵌套集合)
2. 陷阱案例:重复使用Stream
Stream<String> stream = list.stream();
stream.filter(s -> s.length() > 3);
stream.forEach(System.out::println);