我看一下ArrayList源代码,发现remove方法如下:
/**
* Removes the element at the specified position in this list.
* Shifts any subsequent elements to the left (subtracts one from their
* indices).
*
* @param index the index of the element to be removed
* @return the element that was removed from the list
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public E remove(int index) {
if (index >= size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
modCount++;
E oldValue = (E) elementData[index];
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // clear to let GC do its work
return oldValue;
}
为什么它不考虑索引< 0?
时的情况答案 0 :(得分:0)
传递否定索引将在以下行中失败:
E oldValue = (E) elementData[index];
具体来说,对某些负索引会发生对elementData
底层数组的访问。这将导致抛出ArrayIndexOutOfBoundsException
,如文档所述:
抛出以指示已使用非法索引访问数组。索引为负数或大于或等于数组的大小。
因此,ArrayList#remove()
实现不需要做任何额外的事情,因为语言已经处理了负索引的情况。
但是,您可能想知道为什么代码 进行以下检查,如果索引更大而不是大小:
if (index >= size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
进行此检查的原因是因为传递的索引可能是在范围内elementData
但更大而不是实际列表/数组的逻辑大小。换句话说,底层数组的大小不需要(通常也不会)与列表中的实际条目数一致。相反,JVM将根据需要增大或缩小elementData
数组,具体取决于列表的大小和用法。