Stream 的惰性求值、流水线和短路到底是怎么回事?这篇用 peek 和计数器把每个元素经过了哪些阶段打印出来(惰性的 count 行为、parallelStream 的线程数在已有文章里,Spliterator 在后面)。
只建好流水线(没有终结操作)之后日志长度 = 0(什么都没执行)
filter 偶数 → map ×10 → limit(2) → forEach,元素 1..6:
filter(1) filter(2) map(2) →forEach(20) filter(3) filter(4) map(4) →forEach(40) 中间有 sorted():所有元素先过完上游,才开始下游:
up(5) up(3) up(8) up(1) down(1) down(3) down(5) down(8)
没有 sorted():每个元素依次走完整条流水线:
up(5) down(5) up(3) down(3) up(8) down(8) up(1) down(1)无限流 iterate → filter(7 的倍数) → limit(3) → sum = 42,上游一共产生了 21 个元素 一百万个元素的流 findFirst(x > 100) = 101,上游只产生了 101 个元素 limit(5) 在 filter 之前:上游产生了 5 个;limit(5) 在 filter(偶数)之后:上游产生了 10 个(要凑够 5 个偶数) anyMatch(x == 2) = true,检查了 2 个元素 allMatch(x < 3) = false,检查了 3 个元素(遇到第一个不满足的就停)
list.stream().peek(...).count() = 4;peek 执行了吗:没有(流的大小已知,count 直接用大小) 加了 filter 之后 count() = 4;peek 执行了吗:执行了 4 次 只有 map 时 count() = 4;peek 执行了吗:没有 flatMap 之后 count() = 8;peek 执行了吗:执行了 同一个流消费第二次 → IllegalStateException: stream has already been operated upon or closed
JDK 17:
list.stream().peek(...).count() = 4;peek 执行了吗:没有(流的大小已知,count 直接用大小)
加了 filter 之后 count() = 4;peek 执行了吗:执行了 4 次
只有 map 时 count() = 4;peek 执行了吗:没有
flatMap 之后 count() = 8;peek 执行了吗:执行了
JDK 27:
list.stream().peek(...).count() = 4;peek 执行了吗:没有(流的大小已知,count 直接用大小)
加了 filter 之后 count() = 4;peek 执行了吗:执行了 4 次
只有 map 时 count() = 4;peek 执行了吗:没有
flatMap 之后 count() = 8;peek 执行了吗:执行了