您在这里拥有两个流管道。
这些流管道分别由一个源,几个中间操作和一个终端操作组成。
但是中间操作是懒惰的。这意味着除非下游工序需要物料,否则什么也不会发生。如果这样做,则中间操作将完成它所需的所有操作以产生所需的项目,然后再次等待直到请求另一个项目,依此类推。
终端操作通常是“渴望的”。也就是说,他们要求流中完成它们所需的所有项目。
因此,您应该真正将管道视为
forEach向其后面的流询问下一个项目,然后向该流询问其背后的流,依此类推,一直到源。
考虑到这一点,让我们看看您的第一个管道有什么:
Stream.of(1,2,3,4,5,6,7,8,9) .peek(x->System.out.print("nA"+x)) .limit(3) .peek(x->System.out.print("B"+x)) .forEach(x->System.out.print("C"+x));因此,
forEach要求第一项。这意味着“ B”
peek需要一个项目,并向
limit输出流询问该项目,这意味着
limit将需要询问“ A”
peek,该项目将到达源。给定一个项目,一直到
forEach,您就得到第一行:
A1B1C1
该
forEach请求另一个项目,然后另一个。并且每次,请求都在流中传播并执行。但是当
forEach要求第四项时,当请求到达时
limit,它知道它已经给出了允许提供的所有项目。
因此,它不要求“ A”偷看另一个项目。它立即表明它的项目已用尽,因此不再执行任何操作并
forEach终止。
在第二条管道中会发生什么?
Stream.of(1,2,3,4,5,6,7,8,9) .peek(x->System.out.print("nA"+x)) .skip(6) .peek(x->System.out.print("B"+x)) .forEach(x->System.out.print("C"+x));再次,
forEach要求第一项。这被传播回去。但是当到达时
skip,它知道必须先从上游要求6个物料,然后才能通过一个下游物料。因此,它在“
A”上游发出一个请求,在
peek不将其传递到下游的情况下使用它,发出另一个请求,依此类推。因此,“
A”窥视得到一个项目的6个请求并产生6个打印,但是这些项目没有传递下来。
A1A2A3A4A5A6
在发出的第7个请求中
skip,该项目被传递到“ B”窥视,然后从传递给
forEach,因此完成了完整打印:
A7B7C7
然后就像以前一样。在
skip现在,一旦进入一个请求,要求一个项目的上游和下游传递,因为它“知道”它已经完成了它的跳跃任务。因此,其余的打印件将遍及整个管道,直到用尽为止。



