Java如何高效将List拆分为固定数量的子列表,寻求Java8最优实现
Java8 按指定数量拆分List实现方案
核心逻辑
要实现按指定子列表数量拆分,只需要先计算两个核心值:
- 所有子列表的基准元素个数:原列表总长度 / 子列表数量
- 余数:原列表总长度 % 子列表数量,前
余数个子列表各多分配1个元素,刚好可以把所有元素分配完,完全匹配你给出的示例要求
实现代码
通用常规版本
import java.util.ArrayList; import java.util.List; public class ListSplitUtil { /** * 将列表拆分为指定数量的子列表 * @param originalList 原列表 * @param subListCount 指定的子列表数量 * @return 拆分后的子列表集合 */ public static <T> List<List<T>> splitBySubCount(List<T> originalList, int subListCount) { // 边界校验 if (originalList == null || originalList.isEmpty() || subListCount <= 0) { return new ArrayList<>(); } // 子列表数量最多不超过原列表元素个数 subListCount = Math.min(subListCount, originalList.size()); int totalSize = originalList.size(); int baseSize = totalSize / subListCount; int remainder = totalSize % subListCount; List<List<T>> result = new ArrayList<>(subListCount); int offset = 0; for (int i = 0; i < subListCount; i++) { int currentSubSize = baseSize + (i < remainder ? 1 : 0); // 包装一层ArrayList,避免subList返回的视图关联原列表的问题 result.add(new ArrayList<>(originalList.subList(offset, offset + currentSubSize))); offset += currentSubSize; } return result; } public static void main(String[] args) { // 示例1测试 List<Integer> list1 = List.of(1,2,3,4,5,6,7,8); System.out.println(splitBySubCount(list1, 4)); // 输出:[[1, 2], [3, 4], [5, 6], [7, 8]] // 示例2测试 List<Integer> list2 = List.of(1,2,3,4,5,6,7,8,9,10); System.out.println(splitBySubCount(list2, 4)); // 输出:[[1, 2, 3], [4, 5, 6], [7, 8], [9, 10]] } }
Java8 Stream版本
如果你偏好Stream写法,可以用以下实现:
import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; import java.util.stream.IntStream; public static <T> List<List<T>> splitBySubCountStream(List<T> originalList, int subListCount) { if (originalList == null || originalList.isEmpty() || subListCount <= 0) { return new ArrayList<>(); } subListCount = Math.min(subListCount, originalList.size()); int totalSize = originalList.size(); int baseSize = totalSize / subListCount; int remainder = totalSize % subListCount; return IntStream.range(0, subListCount) .mapToObj(i -> { int start = i * baseSize + Math.min(i, remainder); int end = start + baseSize + (i < remainder ? 1 : 0); return new ArrayList<>(originalList.subList(start, end)); }) .collect(Collectors.toList()); }
方案优势
- 逻辑简洁,没有多余的双重循环和Map中间存储,和你原有实现性能一致,可读性和复用性更强
- 泛型实现支持任意类型的列表拆分
- 自带边界校验,避免空指针、非法参数等问题
- 子列表是独立的ArrayList实例,修改原列表不会影响拆分后的子列表内容
内容的提问来源于stack exchange,提问作者sujays
相关产品推荐
相关产品推荐

