Java Stream 的生命周期通常包含哪三个主要步骤?
Java Stream 的生命周期通常包含以下三个主要步骤(阶段):
1. 创建流(Stream Creation)
这是 Stream 生命周期的起点。在这一步,你需要将一个数据源(如集合、数组、I/O 通道或产生器函数)转换成一个 Stream 对象。
- 常见创建方式:
- 从集合(Collection):
list.stream()或set.stream() - 从数组:
Arrays.stream(array) - 直接创建:
Stream.of("a", "b", "c") - 无限流/生成器:
Stream.iterate()或Stream.generate()
- 从集合(Collection):
2. 中间操作(Intermediate Operations)
中间操作用于对流中的元素进行转换、过滤、排序等处理。
- 核心特性(惰性求值/Lazy Evaluation):中间操作不会立即执行具体的计算。它们只是将一个流转换成另一个流,并记录下操作步骤,直到遇到“终端操作”时,所有的中间操作才会一次性执行(这被称为“延迟执行”)。
- 常用操作:
- 过滤:
filter(Predicate) - 转换(映射):
map(Function)、flatMap() - 去重与限制:
distinct()、limit(long)、skip(long) - 排序:
sorted()
- 过滤:
3. 终端操作(Terminal Operation)
终端操作是 Stream 生命周期的终点。
- 核心特性(一次性/Consumable):
- 终端操作会触发实际的计算(遍历数据源并应用中间操作)。
- 终端操作执行完毕后,会返回一个非 Stream 的结果(如 List、Optional、数值或无返回值
void)。 - 流会被关闭(被消费掉),一旦执行了终端操作,该 Stream 就不能再被使用,否则会抛出
IllegalStateException。
- 常用操作:
- 收集结果:
collect(Collectors.toList()) - 遍历:
forEach(Consumer) - 匹配与查找:
anyMatch(),findFirst() - 规约:
reduce(),count()
- 收集结果:
💡 完整代码示例
java
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");
// 1. 创建流 (Creation)
names.stream()
// 2. 中间操作 (Intermediate Operations - 此时不执行计算)
.filter(name -> name.startsWith("A"))
.map(String::toUpperCase)
// 3. 终端操作 (Terminal Operation - 触发计算,流关闭)
.forEach(System.out::println); // 输出: ALICE
右滑查看面试常问