Stream API 详解
一、是什么?
Java Stream 是 JDK 8 引入的 API,用于对集合数据进行声明式处理(如过滤、映射、排序)。它不是数据结构,而是对数据源(集合、数组等)进行高效聚合操作的工具,支持链式调用和并行处理。
二、解决什么问题?
- 简化集合操作:替代繁琐的
for
循环,代码更简洁。 - 提升可读性:链式调用让数据处理流程一目了然。
- 并行优化:
parallelStream()
自动利用多核 CPU 加速计算。 - 延迟执行:中间操作合并后执行,减少迭代次数。
三、核心方法(代码题高频使用)
类型 | 方法 | 作用 | 示例 |
---|---|---|---|
创建 | stream() | 集合转 Stream | list.stream() |
Arrays.stream() | 数组转 Stream | Arrays.stream(new int[]{1,2}) | |
中间操作 | filter(Predicate) | 条件过滤 | .filter(n -> n > 10) |
map(Function) | 元素转换 | .map(String::toUpperCase) | |
sorted() | 排序(自然序或自定义比较器) | .sorted(Comparator.reverseOrder()) | |
distinct() | 去重 | .distinct() | |
limit(n) | 截取前 n 个元素 | .limit(5) | |
终止操作 | collect() | 转换为集合(如 List/Set) | .collect(Collectors.toList()) |
forEach() | 遍历每个元素 | .forEach(System.out::println) | |
count() | 统计元素数量 | .count() | |
reduce() | 聚合计算(如求和) | .reduce(0, Integer::sum) |
JDK 9+ 新增:
takeWhile(Predicate)
:取元素直到条件不满足dropWhile(Predicate)
:丢弃元素直到条件满足
四、应用场景(代码题常见题型)
数据过滤
java// 筛选列表中大于 10 的偶数 List<Integer> result = list.stream() .filter(n -> n > 10) .filter(n -> n % 2 == 0) .collect(Collectors.toList());
对象集合处理
java// 提取所有学生姓名并转为大写 List<String> names = students.stream() .map(Student::getName) .map(String::toUpperCase) .collect(Collectors.toList());
分组与统计
java// 按年龄分组统计人数 Map<Integer, Long> ageCount = students.stream() .collect(Collectors.groupingBy( Student::getAge, Collectors.counting() ));
并行计算(大数据量优化)
java// 并行计算平方和 int sum = list.parallelStream() .mapToInt(n -> n * n) .sum();
链式去重排序
java// 去重后按降序排列 List<Integer> processed = list.stream() .distinct() .sorted(Comparator.reverseOrder()) .collect(Collectors.toList());
五、重要注意事项
流不可复用:
一个 Stream 只能被消费一次,重复操作会抛IllegalStateException
。javaStream<Integer> stream = list.stream(); stream.count(); // 终止操作 stream.forEach(...); // 错误!流已关闭
避免副作用:
不要在filter/map
中修改外部状态(如全局变量),应保持无状态。性能权衡:
- 小数据量优先用
for
循环(Stream 有初始化开销)。 - 大数据量用
parallelStream()
(需线程安全)。
- 小数据量优先用
空指针防护:
使用Optional
处理可能为null
的结果:javaOptional<Integer> max = list.stream() .max(Comparator.naturalOrder()); max.ifPresent(System.out::println);
六、总结
- 核心价值:用声明式语法简化集合操作,提升可读性和并行能力。
- 代码题高频操作:
filter
(过滤)、map
(转换)、collect
(收集结果)、sorted
(排序)。 - 适用场景:集合数据过滤/转换/统计、链式多步处理、并行计算。
- 避坑指南:流不可复用、避免副作用、合理选择并行流。
💡 技巧:在代码题中优先用 Stream 处理集合问题,代码更简洁且易得高分!