如果创建了一个初始容量为5的集合,然后添加了2个元素,在添加第三个元素时指定索引插入
ArrayList<Integer> integers = new ArrayList<>(5);
integers.add(1);
integers.add(10);
integers.add(3,20);
System.out.println(integers.size());
for (Integer integer : integers) {
System.out.println(integer);
}
当添加了2个元素后,此时集合的size是2,但是此时想在下标为3处添加一个元素会报错,按理来说,创建了一个容量是5的集合,想往下标3处添加一个元素是可以的。此时报错如下:
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 3, Size: 2
at java.util.ArrayList.rangeCheckForAdd(ArrayList.java:665)
at java.util.ArrayList.add(ArrayList.java:477)
at com.suanfa.xxb.SeqList.main(SeqList.java:121)
通过查看源码得知,在插入前做了如下判断
private void rangeCheckForAdd(int index) {
if (index > size || index < 0)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
判断当指定的索引大于当前size时,报错,也就是说指定索引最大只能是size,当是size时,相当于就是往集合最后添加一个元素。
为什么会有这个判断?
根本原来是集合在插入元素时,无论是增还是删,都要保证集合的连续性,这样在遍历的时候,迭代器才能根据集合的size,依次获取数据。
加入add方法不做上述校验,那么添加成功后集合元素如下
1,10,null,20,null,而此时size就成了3.
那么在迭代器遍历的时候,会控制迭代器的指针小于size
public boolean hasNext() {
return cursor != size;
}
@SuppressWarnings("unchecked")
public E next() {
checkForComodification();
int i = cursor;
if (i >= size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[lastRet = i];
}
那么此时就会遍历出1,10,null这三个数据来,20不会遍历出来。