如何将ArrayList拆分为3元素数组且后组首元素为前组尾元素?
嘿,我懂你想要的效果了——这其实是滑动窗口式的数组拆分,不是那种一次性跳固定长度的切割。你的原代码因为每次循环步长是3,所以才会把数组切成互不重叠的块,咱们调整下循环逻辑就能实现首尾衔接的效果啦!
问题根源
你当前的separate方法里,循环步长是i += size(也就是每次跳3个元素),所以会从索引0→3→6切割,自然得到[1,2,3],[4,5,6],[7]。而你需要的是每次滑动size-1个元素(也就是2个),让前一个子数组的最后一个元素成为下一个的第一个。
修改后的代码
直接调整separate方法的循环条件和步长即可:
static <T> List<List<T>> separate(List<T> path, final int size) { List<List<T>> separated = new ArrayList<>(); // 循环条件确保每个子数组都能取到size个元素 for (int i = 0; i <= path.size() - size; i += size - 1) { separated.add(new ArrayList<>(path.subList(i, i + size))); } return separated; }
关键逻辑说明
循环条件:
i <= path.size() - size
这个条件保证我们每次截取的子数组都能恰好包含size个元素,不会出现原代码里最后只剩单个元素的情况。比如你的例子中path.size()=7,size=3,7-3=4,所以i最大到4,刚好能截取[5,6,7]。步长设置:
i += size - 1
每次滑动size-1个位置,这样前一个子数组的最后一个元素(索引i+size-1)就会成为下一个子数组的起始索引(i + (size-1)),完美实现首尾衔接的效果。
测试你的例子
当输入ArrayList [1,2,3,4,5,6,7]时:
- i=0 → 截取0到3 →
[1,2,3] - i=0+2=2 → 截取2到5 →
[3,4,5] - i=2+2=4 → 截取4到7 →
[5,6,7]
循环结束,得到的结果完全符合你的需求!
额外说明
如果你的输入列表长度无法刚好分成多个size元素的子数组(比如长度为6,size=3),循环会在i=4时停止(因为6-3=3,i=4>3),最终得到[1,2,3],[3,4,5],不会出现残缺的子数组——如果你需要处理这种边界情况,可以在循环结束后额外判断并添加剩余元素,但根据你的例子需求,当前逻辑已经足够。
内容的提问来源于stack exchange,提问作者Mr Mosby

