Stream流的概念
Stream流是Java 8引入的API,用于以声明式方式处理集合数据。它允许对集合进行高效、链式的并行或串行操作,无需显式编写循环代码。Stream的核心思想是"数据流水线",通过中间操作(如过滤、映射)和终端操作(如收集、遍历)实现复杂的数据处理逻辑。
Stream 流的核心定义
Stream 流是 Java 8 引入的处理集合(Collection)的抽象工具,你可以把它理解成:
把集合(比如 List、Set)想象成一个装满水的水池,Stream 流就是从水池里流出来的 "水流"------ 你可以在水流上做过滤、加工、排序等操作,操作的是 "水流" 里的元素,而不会改变原水池(原集合) 的内容,最终还能把处理后的水流重新收集成新的集合。
它不是数据结构(不存储数据),而是一套 "流水线式" 的操作 API,目的是让集合处理代码更简洁、高效,尤其是处理大数据量时还能轻松实现并行处理。
Stream流的特点
- 不存储数据:Stream 只是操作数据的 "管道",本身不保存任何元素;
- 不修改源数据:所有操作都是基于源集合的副本,原集合不会被改变;
- 惰性求值:只有调用 "终止操作" 时,中间的过滤、映射等操作才会真正执行;
- 可并行化 :用
parallelStream()替代stream(),就能自动实现多线程并行处理,提升大数据量处理效率。
Stream流的操作类型
中间操作(返回新的Stream):
filter(Predicate):按条件过滤元素。map(Function):将元素转换为另一种形式。sorted():对元素排序。
终端操作(触发实际计算):
collect(Collectors.toList()):将结果收集为集合。forEach(Consumer):遍历每个元素。reduce():将元素归约为单个值。
示例代码
java
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
List<String> filtered = names.stream()
.filter(name -> name.length() > 3)
.map(String::toUpperCase)
.collect(Collectors.toList());
// 输出: [ALICE, CHARLIE]
并行流
通过parallelStream()实现多线程处理,提升大数据集处理效率:
java
long count = names.parallelStream()
.filter(name -> name.contains("a"))
.count();
传统方式 vs Stream 流(直观对比)
比如你想从一个数字列表中筛选出偶数,对比两种写法:
1. 传统 for 循环(繁琐)
java
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class TraditionalExample {
public static void main(String[] args) {
List<Integer> nums = Arrays.asList(1,2,3,4,5,6);
List<Integer> evens = new ArrayList<>();
// 手动遍历、筛选、添加
for (Integer num : nums) {
if (num % 2 == 0) {
evens.add(num);
}
}
System.out.println(evens); // 输出 [2,4,6]
}
}
2. Stream 流(简洁)
java
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class StreamExample {
public static void main(String[] args) {
List<Integer> nums = Arrays.asList(1,2,3,4,5,6);
// 流式处理:获取流 → 过滤 → 收集结果
List<Integer> evens = nums.stream()
.filter(num -> num % 2 == 0) // 筛选偶数
.collect(Collectors.toList()); // 收集为列表
System.out.println(evens); // 输出 [2,4,6]
}
}
Stream 流的常见操作分类
Stream 操作分为两类,必须配合使用:
| 类型 | 特点 | 常见方法 |
|---|---|---|
| 中间操作 | 返回 Stream,可链式调用 | filter(过滤)、map(映射)、sorted(排序)、distinct(去重) |
| 终止操作 | 返回非 Stream,触发流的执行 | collect(收集)、forEach(遍历)、count(计数)、sum(求和) |
完整示例(多操作组合)
java
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class StreamFullExample {
public static void main(String[] args) {
// 源数据:学生成绩列表
List<Integer> scores = Arrays.asList(85, 92, 78, 95, 88, 70, 92);
// Stream流处理:筛选80分以上 → 去重 → 降序排序 → 收集为列表
List<Integer> highScores = scores.stream()
.filter(score -> score >= 80) // 中间操作:过滤80分以下
.distinct() // 中间操作:去重
.sorted((a, b) -> b - a) // 中间操作:降序排序
.collect(Collectors.toList()); // 终止操作:收集结果
// 输出结果:[95, 92, 88, 85]
System.out.println("80分以上的去重成绩(降序):" + highScores);
}
}
适用场景
- 大数据集合的过滤、转换、聚合。
- 需要链式编程或并行处理的场景。
- 替代传统循环代码以提高可读性。
注意:Stream不适用于修改数据源或需要复杂状态管理的场景。
总结
- Stream 流是 Java 8 处理集合的高效工具,核心是 "流水线式" 处理,代码更简洁易读;
- Stream 不存储数据、不修改源数据,支持惰性求值和并行处理;
- Stream 操作必须包含 "中间操作 + 终止操作",只有终止操作才会触发真正的计算