最常用、最简洁的方式是使用 guava 的 lists.partition() 方法;若不能引入第三方库,则可用原生 java 8+ 的 stream + sublist() 手动实现,逻辑清晰且无需额外依赖。

Java 中按指定大小将大 List 拆分为多个小批次,最常用、最简洁的方式是使用 Guava 的 Lists.partition() 方法;若不能引入第三方库,则可用原生 Java 8+ 的 Stream + subList() 手动实现,逻辑清晰且无需额外依赖。
用 Guava 快速分批(推荐)
Guava 提供了开箱即用的 Lists.partition(list, size),返回一个 List<list>></list>,每个子列表长度不超过指定 size,最后一个可能更短。
示例:
List<string> bigList = Arrays.asList("a", "b", "c", "d", "e", "f", "g");
List<list>> batches = Lists.partition(bigList, 3);
// 结果:[["a","b","c"], ["d","e","f"], ["g"]]
</list></string>
注意:
- 返回的是视图(view),修改子列表会影响原 list(如需独立副本,可对每个子 list 调用 new ArrayList(sub))
- size 必须 > 0,否则抛 IllegalArgumentException
纯 Java 实现(无依赖)
使用循环 + subList() 是最稳妥的原生方式,兼容所有 JDK 版本,且语义明确:
- 计算总批次数:
(list.size() + size - 1) / size(向上取整) - 每轮用
Math.min(i + size, list.size())防越界 -
subList()返回的是原 list 的逻辑视图,如需深拷贝,包装成新 ArrayList
示例代码:
public static <t> List<list>> partition(List<t> list, int size) {
if (list == null || size > result = new ArrayList();
for (int i = 0; i (list.subList(i, Math.min(i + size, list.size()))));
}
return result;
}
</t></list></t>
用 Stream 辅助(Java 8+,适合函数式风格)
虽不如 subList 直观,但可借助 IntStream 生成索引区间:
int size = 3;
List<list>> batches = IntStream.iterate(0, i -> i i + size)
.mapToObj(i -> bigList.subList(i, Math.min(i + size, bigList.size())))
.map(ArrayList::new) // 转为独立副本
.collect(Collectors.toList());
</list>
⚠️ 注意:
- IntStream.iterate 在 Java 9+ 更推荐用 iterate(0, i -> i i + size) 写法
- 性能略低于传统 for 循环,但可读性对熟悉 Stream 的人较好
实际使用建议
多数业务场景(如分批插入数据库、调用分页接口)中:
- 优先选 Guava —— 简洁、稳定、经过大量验证
- 若项目禁用外部依赖,用原生
for + subList方案,安全可控 - 避免直接返回
subList视图给下游(尤其多线程或后续会修改原 list 时),应显式复制 - 注意空 list 和 size > list.size() 的边界情况,上述方法均能正确处理
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











