起因:最近一直在刷LeetCode,在某一天的解题过程中,创建ArrayList后直接调用了add(int index, E element)的方法,结果返回了一个索引越界的异常。此时脑海中浮现ArrayList的底层实现,ArrayList底层是通过动态数组实现,创建时可以传递初始容量大小,不传参数默认值是10。嘿,那么问题在哪
分析
先上异常
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 1, Size: 0
at java.util.ArrayList.rangeCheckForAdd(ArrayList.java:665)
at java.util.ArrayList.add(ArrayList.java:477)
at Test.main(Test.java:8)
很明显,rangeCheck失败了,并且提示了size为0,基本找到问题所在了,接下来只要去看看rangeCheck的逻辑和size的定义了。话不多说,源码走起,盘他
/**
* A version of rangeCheck used by add and addAll.
*/
private void rangeCheckForAdd(int index) {
if (index > size || index < 0)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
rangeCheckForAdd函数中的判断是index > size || index < 0 就会抛出下标越界异常,再来看看size的定义
/**
* The size of the ArrayList (the number of elements it contains). * * @serial
*/
private int size;
/**
* Returns the number of elements in this list. * * @return the number of elements in this list
*/
public int size() {
return size;
}
从size定义的注释和size()函数就能很明显的看出,size代表的是ArrayList中有多少个元素。只有当调用ArrayList的add()和remove()方法时,才会对size进行操作(size++, --size),所以当我们新建ArrayList时,size=0,此时调用add(E element)直接添加元素是没有问题的,而此时调用add(int index, E element),若index > 0就会抛出下标越界异常
总结:ArrayList中的rangeCheck是与集合内的元素总数做比较,而不是与底层的数组长度做比较
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。