Java中的管道流操作包含了三部分:数据源(source)、中间操作(intermediate operations)、终止操作(terminal operation),其中中间操作时lazy的,终止操作是eager的,于是终止操作非常eager的向upStream请求数据,upStream在向upupStream请求数据等……

limit

  1. Stream.of(1,2,3,4,5,6,7,8,9)
  2. .peek(x->System.out.print("\nA"+x))
  3. .limit(3)
  4. .peek(x->System.out.print("B"+x))
  5. .forEach(x->System.out.print("C"+x));

forEach(terminal operation)需要第一个元素,问上游B peek要,于是乎limit->A peek->source,之后再从源向downStream一一传递,但是上例中有一个limit,这意味着forEach第四次请求元素时,发现已经到达极限了,不再向upStream A peek请求数据。

所以上面的输出是这样的:

  1. A1B1C1
  2. A2B2C2
  3. A3B3C3

skip

  1. Stream.of(1,2,3,4,5,6,7,8,9)
  2. .peek(x->System.out.print("\nA"+x))
  3. .skip(6)
  4. .peek(x->System.out.print("B"+x))
  5. .forEach(x->System.out.print("C"+x));

forEach(terminal operation)需要第一个元素,问上游B peek要,于是乎limit->A peek->source,之后再从源向downStream一一传递,但是上例中有一个skip,这意味着skip会从其upStream要6个元素并“吞掉”不向downStream传递。

所以上面的输出是这样的:

  1. A1
  2. A2
  3. A3
  4. A4
  5. A5
  6. A6
  7. A7B7C7
  8. A8B8C8
  9. A9B9C9

参考资料:https://stackoverflow.com/questions/32414088/java-8-stream-difference-between-limit-and-skip/