You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何根据指定分片数创建近似等长的对象子列表?

问题描述

我有一个包含N个对象的ArrayList,对象结构如下:

[
    {
        "firstName": "Todd",
        "lastName": "Jones"
    },
    {
        "firstName": "Mike",
        "lastName": "Johnson"
    },
    {
        "firstName": "Tina",
        "lastName": "Jones"
    },
    {
        "firstName": "Tommy",
        "lastName": "Wiseau"
    },
    ....
]

我需要根据传入的当前分片索引(chunkIndex)和总分片数(numOfChunks),把列表拆成近似等份的子任务。现在写的逻辑没处理无法整除的情况,导致索引出错,请问怎么确保subList的索引始终正确?

示例场景:9个姓名对象,拆成2个近似等长数组,取第1片。

当前有问题的逻辑代码:

final int namesCount = names.size();
final int namesDividedCount = namesCount / numOfChunks;
int startIndex, endIndex;

if (chunkIndex == 1) {
  startIndex = 0;
  endIndex = namesDividedCount;
} else if (chunkIndex == numOfChunks) {
  startIndex = namesCount - namesDividedCount;
  endIndex = namesCount;
} else {
  startIndex = ((chunkIndex - 1) * namesDividedCount) + 1;
  endIndex = chunkIndex * namesDividedCount;
}
return names.subList(startIndex, endIndex);
修正方案

原有逻辑的核心问题有两个:

  1. 没处理无法整除时的余数:比如9个元素分2片,按原有逻辑会分成4和4,直接漏掉1个元素
  2. 中间分片的startIndex多了+1,导致分片之间出现元素遗漏

下面提供两种可靠的实现方式,都能解决整除/非整除场景的索引问题:

方式一:余数优先分配给前N个分片

这种方式会让前面的分片比后面的多1个元素(当无法整除时),比如9分2片,结果是5、4,更符合"近似等长"的直觉:

final int namesCount = names.size();
final int baseSize = namesCount / numOfChunks;
final int remainder = namesCount % numOfChunks;

// 计算当前分片的起始索引
int startIndex = (chunkIndex - 1) * baseSize + Math.min(chunkIndex - 1, remainder);
// 计算当前分片的结束索引
int endIndex = startIndex + baseSize + (chunkIndex <= remainder ? 1 : 0);

// 兜底处理,防止极端情况索引越界(逻辑上不会触发,但加一层更安全)
startIndex = Math.max(0, startIndex);
endIndex = Math.min(namesCount, endIndex);

return names.subList(startIndex, endIndex);

验证示例:9个元素,numOfChunks=2,chunkIndex=1

  • baseSize=4,remainder=1
  • startIndex=(1-1)*4 + min(0,1) = 0
  • endIndex=0+4 + (1<=1?1:0) =5
  • 最终取0到5的子列表,共5个元素,符合预期

方式二:整数除法自动分配余数

这种写法更简洁,余数会自动分配给后面的分片,比如9分2片,结果是4、5:

final int namesCount = names.size();
int startIndex = (namesCount * (chunkIndex - 1)) / numOfChunks;
int endIndex = (namesCount * chunkIndex) / numOfChunks;

return names.subList(startIndex, endIndex);

验证示例:9个元素,numOfChunks=2,chunkIndex=1

  • startIndex=(90)/2=0,endIndex=(91)/2=4 → 取0-4的子列表,共4个元素
  • chunkIndex=2时,startIndex=(9*1)/2=4,endIndex=9 → 取4-9的子列表,共5个元素

两种方式都能保证所有元素被覆盖,不会出现遗漏或索引越界的问题,根据你的实际需求选择即可。

内容的提问来源于stack exchange,提问作者spaceghost

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 14:47:51