ArrayList.add(index,element)报IndexOutOfBoundsException的解决办法
问题根因
ArrayList的public void add(int index, E element)方法对入参index有严格的合法性校验:允许传入的索引范围为 0 ≤ index ≤ 当前列表的size值,只要超出这个范围就会直接抛出IndexOutOfBoundsException。
你遇到的错误在第一次调用list.add(5, element5)时就已经触发了:刚初始化完成的ArrayList内部记录的实际元素个数size=0,此时合法的插入索引只能是0,传入5完全不符合校验规则,后续的list.add(3, element3)根本没有执行机会。
注意不要混淆ArrayList的初始容量和实际元素长度:哪怕你初始化时写了new ArrayList<>(10),也只是提前给底层数组分配了10个位置的内存,列表实际持有的元素数依然是0,传入大于0的索引插入还是会报错。
另外补充:add(index, element)是插入语义,执行后会把index位置及之后的所有元素整体后移一位,列表长度+1,不是直接替换index位置的元素。
修复方案
根据你的实际使用场景选对应方案即可:
- 如果你的需求本身就是按非连续的索引存储元素,不需要严格的连续顺序列表特性,直接换掉ArrayList:普通Java环境用
HashMap<Integer, 你的元素类型>存索引和元素的映射关系即可,Android环境可以用更省内存的SparseArray,等所有元素存完再按需转成列表就行,完全不会有索引越界问题。 - 如果必须使用ArrayList,且需要在指定索引位置放对应元素,先提前填充占位值把列表的size撑到你需要的最大索引+1,再执行插入/替换操作:
// 假设你要用到的最大索引是5 int maxIndex = 5; List<你的元素类型> list = new ArrayList<>(); // 先填充占位,把列表size拉到maxIndex + 1 for (int i = 0; i <= maxIndex; i++) { list.add(null); // 可替换为你需要的默认占位值 } // 之后就可以按任意索引顺序操作了 list.add(5, element5); list.add(3, element3); // 如果是要替换对应位置的元素,不需要挪动元素的话,直接用set语义更准确: // list.set(5, element5); // list.set(3, element3);
- 如果你只是想按调用顺序把元素放进列表,不需要指定位置,直接用无索引的
add(E element)方法即可,元素会自动追加到列表末尾,不需要手动维护索引值。
内容的提问来源于stack exchange,提问作者Mr. 17
相关产品推荐
相关产品推荐

