一、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);