中间操作返回Stream<T>、惰性执行、可链式调用;终止操作返回非Stream类型、触发实际计算、执行后流失效。

区分中间操作和终止操作,关键看两点:返回值类型和执行时机。
看方法的返回值类型
中间操作总是返回 Stream<T> 类型,支持链式调用;终止操作返回的是非 Stream 类型,比如 List、Long、void、Optional 或自定义对象。
- 中间操作示例:filter、map、sorted、limit、skip、distinct、flatMap —— 全部返回 Stream,可继续接其他中间或终止操作
- 终止操作示例:collect、forEach、count、findFirst、anyMatch、reduce、toArray —— 返回值不再是 Stream,调用后流就“消耗完毕”,不能再复用
看是否真正触发数据处理
中间操作是惰性的,只记下要做什么,不实际处理元素;终止操作才是“发号施令”的那一个,它一出现,整条流水线才从头开始执行。
- 写完 list.stream().filter(x -> x > 0).map(String::valueOf),什么都没发生
- 加上 .collect(Collectors.toList()),这时 filter 和 map 才真正逐个元素运行
- 同一个 Stream 只能执行一次终止操作。第二次调用会抛出 IllegalStateException
看能否多次使用同一个 Stream
Stream 是一次性资源,不可重复消费。
- 中间操作可以无限叠加(只要没触发终止),但不会改变原始 Stream 的状态
- 一旦执行了 forEach 或 collect,该 Stream 实例就失效,再调用任何操作都会报错
- 需要重复处理?得重新从数据源创建 Stream,比如 list.stream() 再来一遍
简单记忆口诀
中间操作:返回 Stream,不干活,只排队;
终止操作:不返 Stream,真干活,干完废。


















