admin管理员组文章数量:1611946
文章目录
- 问题
- 实验
- 追根究底
- 查看ArrayList的构造函数
- 查看ArrayList的add(index, data)函数
- 总结
- 总结图
JDK版本: openJDK 1.8
问题
在ArrayList中,size跟capacity是一样的东西吗?
实验
在ArrayList中有这么一个构造函数可以让我们指定初始的容量(Capacity)。
public ArrayList(int initialCapacity);
然后我们可以利用这个构造函数来创建一个ArrayList并在构造函数里指定初始容量为10。接着尝试在下标为9的位置插入一个数据。
ArrayList list = new ArrayList<Integer>(10);
int index = 9;
int data = 0;
list.add(index, data);
原本我的想法是,既然我们的初始容量可以容纳10个数据,那么在下标为9的位置插入一个数据应该是没有问题的。然而程序却抛出了一个异常错误:
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 9, Size: 0
根据这个异常错误信息,往下标9的位置插入数据超越了数组的界限。
追根究底
这就很奇怪了,明明我们ArrayList的Capacity是10,为什么下标9会越界呢?
查看ArrayList的构造函数
为了寻找原因,我打开了ArrayList的源代码,首先我们来看一下在ArrayList中可以指定Capacity的构造函数:
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
// 我们传入的参数为10,因此 ArrayList 会初始化一个大小为 10 的 Object 数组
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}
由于我们传入的initialCapacity参数为10,因此ArrayList会初始化一个大小为10的 Object 数组来储存我们的数据。
到此为止看上去都很合理,ArrayList的底层数组实际上是足够大到可以让我们往下标9的位置插入数据,那么问题会是出在哪里呢?
查看ArrayList的add(index, data)函数
我们的下一步就是要查看ArrayList中可以往指定下标位置插入数据的add(index, data)函数。
public void add(int index, E element) {
// 这个函数看起来很可疑
rangeCheckForAdd(index);
ensureCapacityInternal(size + 1); // Increments modCount!!
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
elementData[index] = element;
size++;
}
从源代码中,我们发现有一个函数看起来很可疑:rangeCheckForAdd(index)
根据名字来看似乎是在确认数组是否越界。ctrl + 左键 点击该函数查看源代码:
private void rangeCheckForAdd(int index) {
// 原来是根据 size 来判断数组是否越界
if (index > size || index < 0)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
从代码中可以看出,ArrayList是使用size属性来确定数组是否越界,并非capacity。
那么size属性是从哪里来的呢?
如果我们再看回add(index, data)函数,就会发现ArrayList在add操作的最后做了size++的操作。
让我们再来看看add(E e)函数的源代码:
public boolean add(E e) {
ensureCapacityInternal(size + 1);
elementData[size++] = e; // 在末尾插入数据之后,size++
return true;
}
可以看到,add(E e)函数会在数组的末尾插入数据,并进行size++的操作。
也就是说,只有当插入新数据的时候,size才会往上提升。
同样的,如果我们检查 remove(int index) 的源代码,也会发现它会进行size–的操作。
因此,size表示的是数组中元素的数量,并非数组的容量。
总结
在检查了ArrayList的源代码之后,我们可以总结出以下结论:
- 在ArrayList中,size与capacity是不同的概念
- size指的是ArrayList中元素的数量
- capacity指的是在ArrayList底层实现中Object数组的大小,也可以理解为ArrayList的容量
- ArrayList是使用size来判断数组是否越界
总结图
这张总结图大家可以收藏一下,用作复习。
如果大家觉得文章有用的话,请帮忙点个赞,谢谢!
本文标签: 中你区别ArrayListCapacitysize
版权声明:本文标题:ArrayList中你分得清楚size与capacity的区别吗? 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://m.elefans.com/dongtai/1728620195a1166255.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论