关于java:ArrayList不为人知的小陷阱

1次阅读

共计 1138 个字符,预计需要花费 3 分钟才能阅读完成。

起因:最近始终在刷 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 是与汇合内的元素总数做比拟,而不是与底层的数组长度做比拟

正文完
 0