为什么以下返回 IndexOutOfBoundsException?(索引 5,尺寸 0)
gridList = new ArrayList<Integer>(9);
gridList.add(5, 2);
我的印象是构造函数调用将我的数组列表初始化为大小。
我对java很陌生,所以很抱歉。
为什么以下返回 IndexOutOfBoundsException?(索引 5,尺寸 0)
gridList = new ArrayList<Integer>(9);
gridList.add(5, 2);
我的印象是构造函数调用将我的数组列表初始化为大小。
我对java很陌生,所以很抱歉。
调用该构造函数仅指定初始容量,但对 ArrayList 的大小没有影响(在添加任何内容之前,大小始终为零)。这在文档中进行了解释,并通过打印出 ArrayList 来证明:
ArrayList<Integer> gridList = new ArrayList<Integer>(9);
System.out.println(gridList);
Output: []
如果您想用 9 个整数(例如,九个零)初始化 ArrayList,请尝试以下“便捷实现”:
ArrayList<Integer> gridList = new ArrayList<Integer>(Collections.nCopies(9, 0));
System.out.println(gridList);
Output: [0, 0, 0, 0, 0, 0, 0, 0, 0]
如您所见,这会在初始化期间用值填充 ArrayList,因此您现在可以在gridList.add(5, 2);
没有IndexOutOfBoundsException
.
ArrayList
初始化为容量9 ,但列表为空。因此,您不能在位置 5 添加元素,因为该位置在列表中不存在。
请关注 ArrayList 的源码,可以看到大小和容量是不同的概念。
checkBoundInclusive()
methodindex
与size
not进行比较capacity
。
public ArrayList(int capacity)
{
// Must explicitly check, to get correct exception.
if (capacity < 0)
throw new IllegalArgumentException();
data = (E[]) new Object[capacity];
}
public void add(int index, E e)
{
checkBoundInclusive(index);
modCount++;
if (size == data.length)
ensureCapacity(size + 1);
if (index != size)
System.arraycopy(data, index, data, index + 1, size - index);
data[index] = e;
size++;
}
private void checkBoundInclusive(int index)
{
// Implementation note: we do not check for negative ranges here, since
// use of a negative index will cause an ArrayIndexOutOfBoundsException,
// a subclass of the required exception, with no effort on our part.
if (index > size)
throw new IndexOutOfBoundsException("Index: " + index + ", Size: "
+ size);
}
它仍然是一个空列表(大小为 1,唯一可用的索引为 0)。只是容量是9。一旦容量达到容量,ArrayList
就会扩大。
注意:大小和容量是两个不同的东西。
正如其他人在这种情况下指出的那样,您在位置 5 处输入了 en 元素,但那里什么都没有,之前也没有元素 - 看这里:
ArrayList<Integer> g = new ArrayList<Integer>(9);
g.add(0, 10);
g.add(1, 20);
g.add(2, 30);
g.add(3, 40);
for(Integer v: g) System.out.print(v + " ");
System.out.println();
g.add(2,99);
for(Integer v: g) System.out.print(v + " ");
System.out.println();
g.add(88); // use this to just push value at the end
for(Integer v: g) System.out.print(v + " ");
System.out.println();
产量:
10 20 30 40
10 20 99 30 40
10 20 99 30 40 88