skip(n)跳过流前n个元素返回新流,惰性不触发执行;若流长≤n则为空流;常与limit配合分页,但需注意数据源有序性及性能差异。

skip(n) 会跳过流的前 n 个元素,返回剩余部分组成的新流。它不修改原流,也不触发执行,属于惰性中间操作。
skip 的基本行为
调用 skip(n) 后,流中前 n 个元素被丢弃,后续元素按原有顺序构成新流。若流长度 ≤ n,则结果为空流(不抛异常)。例如:
-
List.of(1,2,3,4,5).stream().skip(2)→ 流含3,4,5 -
Stream.empty().skip(10)→ 仍是空流 -
Stream.iterate(0, i -> i+1).skip(100)→ 跳过前100个,从100开始无限流
与 limit 配合实现分页
skip 常和 limit 组合用于模拟分页逻辑,比如取第 2 页(每页 10 条):
- 先
skip(10)跳过第 1 页 - 再
limit(10)取下 10 条 - 完整写法:
stream.skip((page - 1) * size).limit(size)
注意:这对有序、可重复遍历的集合较安全;对无序流或数据库查询场景,应优先使用数据库原生分页。
立即学习“Java免费学习笔记(深入)”;
性能与注意事项
skip 的开销取决于数据源类型:
- 对 ArrayList 等支持随机访问的集合,skip 实际是跳过索引,较快
- 对 LinkedList 或 IO 流等只能顺序读取的源,需逐个消费前 n 个元素,时间复杂度 O(n)
- 在并行流中,skip 无法保证跳过的一定是“逻辑上前 n 个”,因为并行处理会打乱顺序 —— 所以 skip 要求流是 有序的(ordered),否则结果不可预测
慎用 skip 的典型场景
以下情况应避免依赖 skip:
- 对未排序的数据库查询结果流直接 skip + limit 分页(可能漏数据或重复)
- 在无限流(如
Stream.generate())中大数值 skip(可能长时间阻塞) - 与 distinct() 或 sorted() 混用时:distinct 不保证顺序,sorted 后再 skip 是安全的,但 distinct 后 skip 语义模糊

















