skip()和limit()组合分页需校验边界:当page×size≥集合长度时应主动返回空或抛异常;page起始值(0或1)决定偏移量公式,且须校验page≤0或size≤0等非法参数。

Java Stream 的 skip() 和 limit() 组合做分页,看似简单,但几个关键边界情况处理不当,容易返回空数据、越界异常或逻辑错乱。
跳过数量超出集合长度
skip(n) 当 n 大于等于集合元素总数时,不会报错,而是返回空流;limit() 同理。这意味着:
– 若请求第 100 页(每页 20 条),但总数据仅 50 条,skip(1980) 会静默跳过全部元素,最终 collect() 得到空列表。
– 业务上应主动校验:若 page * size >= list.size(),直接返回空集合或抛出 IllegalArgumentException,避免前端误判为“无数据”而非“页码无效”。
页码与页大小的合法性检查
常见疏漏是忽略参数非法场景:
– page 从 0 还是 1 开始?若按 1 起始(如第 1 页),计算偏移量应为 (page - 1) * size;若用 0 起始,则直接 page * size。
– size ≤ 0 或 page 会导致 <code>skip() 抛 IllegalArgumentException(因参数为负 long);应在调用前拦截并统一返回空或提示。
流不可重复消费导致的复用错误
Stream 只能遍历一次。以下写法是典型错误:
Stream<t> s = data.stream();<br>s.skip(0).limit(10).collect(...);<br>s.skip(10).limit(10).collect(...); // IllegalStateException</t>
正确做法是每次分页都重新创建流:
data.stream().skip(...).limit(...).collect(...)。尤其在循环分页或 Web 接口多页请求中,必须确保源头是可重放的集合(如 List),而非一次性流(如 Files.lines())。大数据量下的性能陷阱
skip(n) 内部需顺序遍历前 n 个元素(即使不消费),时间复杂度 O(n);limit(m) 后续仍要遍历 m 个。例如取第 1000 页(每页 20 条),需跳过 19980 个元素——对 10 万条内存数据,这已带来明显延迟和 GC 压力。
– 小于几千条数据可用此方案;
– 超过 1 万条,建议改用数据库原生分页(OFFSET/LIMIT 或游标);
– 禁止在 service.findAll().stream()... 中直接链式调用,否则每次分页都触发全量查询。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











