什么是 Stream? Stream 是 Java 8 引入的一种数据处理管道,它不是数据结构,不存储元素,而是对集合、数组等数据源进行一系列操作的抽象。
核心优势:
✅ 一句话总结:Stream 让数据处理像流水线一样流畅。
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
Stream<String> stream = names.stream();String[] arr = {"Alice", "Bob", "Charlie"};
Stream<String> stream = Arrays.stream(arr);Stream<String> stream = Stream.of("Alice", "Bob", "Charlie");IntStream.range(1, 10):生成整数范围流Stream.iterate(0, n -> n + 2):迭代生成流Files.lines(path):读取文件行作为流Stream 操作分为两类:中间操作 和 终结操作。
特点:惰性执行,返回新的 Stream,可链式调用。
方法 | 说明 | 示例 |
|---|---|---|
filter(Predicate) | 过滤符合条件的元素 | .filter(s -> s.length() > 4) |
map(Function) | 转换元素类型或值 | .map(String::length) |
flatMap(Function) | 扁平化映射,将流中的流合并 | .flatMap(str -> Arrays.stream(str.split(""))) |
distinct() | 去重(基于 equals) | .distinct() |
sorted() | 排序(自然序或自定义) | .sorted(Comparator.reverseOrder()) |
limit(n) | 截取前 n 个元素 | .limit(5) |
skip(n) | 跳过前 n 个元素 | .skip(2) |
peek(Consumer) | 调试用,对每个元素执行操作但不改变流 | .peek(System.out::println) |
⚠️ 注意:中间操作不会立即执行,只有遇到终结操作时才会“触发”整个流水线。
特点:立即执行,产生结果或副作用,执行后 Stream 不可再用。
方法 | 说明 | 示例 |
|---|---|---|
forEach(Consumer) | 遍历并处理每个元素 | .forEach(System.out::println) |
collect(Collector) | 收集结果到容器(List、Set、Map等) | .collect(Collectors.toList()) |
count() | 统计元素数量 | .count() |
anyMatch(Predicate) | 是否存在匹配元素 | .anyMatch(s -> s.startsWith("A")) |
allMatch(Predicate) | 是否全部匹配 | .allMatch(s -> s.length() > 0) |
noneMatch(Predicate) | 是否无匹配 | .noneMatch(s -> s.isEmpty()) |
findFirst() | 返回第一个元素(Optional) | .findFirst() |
reduce() | 聚合操作(如求和) | .reduce(0, Integer::sum) |
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
// 计算偶数的平方,并收集到新列表
List<Integer> result = numbers.stream()
.filter(n -> n % 2 == 0) // 筛选偶数
.map(n -> n * n) // 计算平方
.collect(Collectors.toList()); // 收集结果
System.out.println("偶数的平方: " + result); // [4, 16, 36, 64, 100]
// 直接输出(不收集)
System.out.println("直接输出:");
numbers.stream()
.filter(n -> n % 2 == 0)
.map(n -> n * n)
.forEach(System.out::println);🔍 执行流程:
numbers → filter → map → collect/forEach
List<String> employees = Arrays.asList(
"Alice", "Bob", "Charlie", "Alice", "David", "Bob", "Eve");
// 方式一:先处理再统计
long uniqueCount = employees.stream()
.distinct() // 去重
.sorted() // 排序
.peek(System.out::println) // 调试输出
.count(); // 统计数量
// 方式二:收集去重排序后的列表
List<String> sortedUnique = employees.stream()
.distinct()
.sorted()
.collect(Collectors.toList());
System.out.println("去重排序后: " + sortedUnique);
System.out.println("员工总数: " + uniqueCount);💡
peek()是中间操作,常用于调试,查看流中每一步的数据变化。
使用 parallelStream() 可将流操作并行化:
List<Integer> numbers = Arrays.asList(1, 2, 3, ..., 1000000);
// 串行处理
long sum1 = numbers.stream()
.mapToInt(Integer::intValue)
.sum();
// 并行处理(利用多核 CPU)
long sum2 = numbers.parallelStream()
.mapToInt(Integer::intValue)
.sum();⚠️ 注意事项:
类型 | 特点 | 常见方法 |
|---|---|---|
中间操作 | 惰性执行,返回 Stream | filter, map, sorted, limit, distinct |
终结操作 | 立即执行,产生结果 | forEach, collect, count, findFirst, reduce |
并行流 | 利用多核提升性能 | parallelStream() |
Stream 的核心思想是“声明式编程”——你只需告诉 JVM “要做什么”,而不用关心“怎么做”。掌握 Stream,让你的 Java 代码更现代、更高效!
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。