版本:基于 Java 17 & Java 21 LTS
Stream API 是 Java 8 引入的最具革命性的特性之一。它让你可以以声明式的方式处理数据集合,就像编写 SQL 查询一样简单。本篇将通过实战案例带你精通 Stream 的核心用法。
1. Stream 的生命周期
一个 Stream 操作通常分为三个阶段:
数据源 (Source):如
List,Set,数组。中间操作 (Intermediate Operations):返回一个新的 Stream,可以链式调用。
终端操作 (Terminal Operations):触发计算并返回结果,一旦执行,Stream 就会关闭。
2. 核心中间操作 (Filter & Map)
Filter (过滤)
根据条件筛选元素。
var names = List.of("Alice", "Bob", "Charlie", "David");
var result = names.stream()
.filter(name -> name.startsWith("A"))
.toList(); // AliceMap (映射/转换)
将元素转换成另一种形式。
var lengths = names.stream()
.map(String::length) // 转换成名字的长度
.toList(); // [5, 3, 7, 5]3. 核心终端操作 (Collect & ForEach)
Collect (收集)
将 Stream 转换回集合或其他形式。
import java.util.stream.Collectors;
var userMap = names.stream()
.collect(Collectors.toMap(
name -> name, // Key
name -> name.length() // Value
));Reduce (规约)
将所有元素合并成一个值(如求和、求最大值)。
var sum = List.of(1, 2, 3, 4).stream()
.reduce(0, Integer::sum); // 104. 排序与去重 (Sorted & Distinct)
var numbers = List.of(3, 1, 4, 1, 5, 9);
var sortedUnique = numbers.stream()
.distinct() // 去重
.sorted() // 排序
.toList(); // [1, 3, 4, 5, 9]5. 并行流 (Parallel Streams)
如果你处理的是海量数据,可以使用并行流来利用多核 CPU 的性能。
var hugeList = java.util.stream.LongStream.rangeClosed(1, 1_000_000).boxed().toList();
// 串行
long start = System.currentTimeMillis();
hugeList.stream().map(Math::sqrt).count();
System.out.println("串行耗时: " + (System.currentTimeMillis() - start));
// 并行
start = System.currentTimeMillis();
hugeList.parallelStream().map(Math::sqrt).count();
System.out.println("并行耗时: " + (System.currentTimeMillis() - start));注意:并行流并不总是更快。对于简单操作或小数据量,线程管理的开销反而会让它变慢。
6. Java 16+ 新特性:.toList()
在 Java 16 之前,你需要写长长的 .collect(Collectors.toList())。现在可以直接写 .toList(),它返回的是一个不可变的列表。
// 现代写法
var modernList = Stream.of("a", "b").toList(); 本章小结
第九篇我们实战了:
Stream 的三个阶段:源、中间操作、终端操作。
如何使用
filter筛选数据,map转换数据。使用
Collectors进行复杂的结果收集。利用
parallelStream处理大数据。Java 16+ 带来的简洁
.toList()语法。
下一篇预告:多线程与并发基础 (Thread, Runnable, ExecutorService, Virtual Threads)