Java Stream中间操作惰性执行、返回Stream,可链式调用;终端操作立即触发、返回非Stream结果,执行后流关闭不可重用。

区分 Java Stream 的终端操作和中间操作,关键看两点:**是否立即执行**、**返回值类型**。中间操作只是“搭流水线”,不干活;终端操作才是“按开关”,真正开始处理数据。
看返回值:是 Stream 还是别的类型
中间操作一定返回 Stream 类型,比如 filter()、map()、sorted()、distinct()、limit()。它们可以连着写,形成链式调用:
-
list.stream().filter(x -> x > 0).map(String::valueOf).sorted()—— 每一步都返回新 Stream,但此时什么都没算
终端操作返回的**不是 Stream**,而是具体结果或 void,比如 collect() 返回 List,count() 返回 long,anyMatch() 返回 boolean,forEach() 是 void。
看执行时机:惰性 vs 立即触发
中间操作是惰性的(lazy),定义好流程后不会立刻遍历数据;只有遇到终端操作,整条链才一次性从头到尾执行一遍。
立即学习“Java免费学习笔记(深入)”;
- 写了
stream.filter(...).map(...)却没接终端操作?代码跑完也不会处理任何元素 - 一旦调用
collect(Collectors.toList())或findFirst(),所有前面的中间操作才真正运行
看能否重复使用:流只能消费一次
终端操作执行后,Stream 就关闭了,不能再调用任何操作(包括再加中间操作或另起终端操作)。
- 错误示例:
Stream s = list.stream().filter(...); s.collect(...); s.count();—— 第二行会抛IllegalStateException - 正确做法:需要多次使用,就得重新创建 Stream,比如再调一次
list.stream()
常见操作归类速查
典型中间操作(返回 Stream,可链式):filter、map、flatMap、sorted、distinct、limit、skip、peek
典型终端操作(触发执行,返回非 Stream):collect、forEach、reduce、count、anyMatch、allMatch、noneMatch、findFirst、findAny、min、max


















