自定义迭代器实现分页加载的核心是将分页逻辑内聚于迭代器状态机中,通过封装页码、页大小、缓存等状态,惰性加载、按需取批、自动终止,并支持多数据源与资源管控。

自定义迭代器实现分页加载控制,核心在于把“按批取数据”这个行为封装进迭代器的状态机中,让每次 next() 调用自动触发下一页请求或计算,并在无更多数据时自然终止。它不依赖外部循环条件,而是将分页逻辑内聚在迭代器内部。
封装分页状态与加载边界
迭代器需持有当前页码、每页大小、是否还有下一页等状态,并在 hasNext() 中决定是否继续加载:
- 初始化时只设参数,不预加载数据:避免首次调用就拉取全部第一页,保持惰性
-
hasNext()内部检查缓存是否为空;若空,则调用loadPage(currentPage)加载一批,再判断结果长度是否达满额(如返回少于pageSize条,说明到底) - 加载成功后缓存这批数据,供后续多次
next()消费,直到用完才触发下一次加载
支持多种数据源的统一接口
无论数据来自内存数组、HTTP 接口还是数据库游标,只要实现相同的 load(int page, int size) 抽象方法,就能复用同一套迭代器骨架:
- 内存分页:直接
list.subList((page-1)*size, Math.min(page*size, list.size())) - API 分页:带
page或cursor参数发起请求,解析响应并提取items和next_cursor - 数据库分页:生成
LIMIT offset, sizeSQL,或使用游标式查询(如WHERE id > ? ORDER BY id LIMIT size)
防止无限加载与资源失控
裸迭代器容易被滥用(如 list(iterator) 全量展开),必须主动加约束:
- 在
load()内部设置最大页数限制(如最多加载 50 页),超限时返回空列表并标记hasMore = false - 对耗时操作(如网络请求)加入失败重试计数或超时控制,避免单次
next()卡死 - 提供可选的
close()或reset()方法,允许手动释放连接、清空缓存或重置页码
适配前端滚动加载场景
前端“无限滚动”本质是按需拉取固定尺寸批次,这与迭代器的 take(n) 行为高度一致:
- 后端暴露一个迭代器实例(如 Java 的
MyPageIterator),前端每次滚动到底部时调用it.nextBatch(20)(可封装为便捷方法) - 不推荐让前端直接用
for...of遍历——除非明确限定轮次,否则可能意外触达末页甚至阻塞主线程 - 更安全的做法是:前端传入
batchSize,后端迭代器返回一个List<t></t>,而非裸迭代器对象

















