Java中复制Truck对象列表时抛出IndexOutOfBoundsException异常求助
排查Java深拷贝Truck列表时的
IndexOutOfBoundsException异常 问题原因分析
你遇到的IndexOutOfBoundsException: Source does not fit in dest异常,根源出在Truck类的带参构造函数里的Collections.copy(this.route, route)调用上。
Collections.copy()有个严格的要求:目标集合的实际元素数量必须大于等于源集合的元素数量。你在Truck类中默认初始化的this.route是一个空的ArrayList(元素数为0),而传入的源route有7个元素([0, 9, 11, 1, 15, 3, 0]),这时候调用Collections.copy时,目标集合没有足够的位置来存放源元素,直接触发了边界异常。
另外还要注意,你的cloneList方法里有个小问题:循环遍历的是类的静态变量trucks,而不是传入的方法参数trucksList,这会导致拷贝逻辑不符合预期,需要一并修正。
解决方法
1. 修正Truck的带参构造函数(推荐方案)
直接放弃Collections.copy,改用ArrayList的拷贝构造函数,它会自动初始化足够的容量并完成元素复制,简洁又高效:
static class Truck { ArrayList<Integer> route = new ArrayList<Integer>(); double weight = 0; int route_weight = 0; Truck() { } // 修改后的带参构造函数 Truck(ArrayList<Integer> route) { this.route = new ArrayList<>(route); } // getters and setters }
2. 若坚持使用Collections.copy的修正方案
如果一定要用Collections.copy,需要先确保目标集合的实际元素数量足够容纳源元素,比如先创建一个和源集合大小一致的空元素集合:
Truck(ArrayList<Integer> route) { // 创建一个和源集合大小相同、填充null的集合,保证元素数量足够 this.route = new ArrayList<>(Collections.nCopies(route.size(), null)); Collections.copy(this.route, route); }
3. 修正cloneList的遍历逻辑
把循环遍历的对象改成方法参数trucksList,确保拷贝的是传入的列表:
public static ArrayList<Truck> cloneList(ArrayList<Truck> trucksList) { ArrayList<Truck> clonedList = new ArrayList<Truck>(); // 遍历传入的参数列表,而非静态变量trucks for (Truck truck : trucksList) { Truck w=new Truck(truck.getroute()); clonedList.add(w); } return clonedList; }
内容的提问来源于stack exchange,提问作者Sirtek
相关产品推荐
相关产品推荐

