ArrayList 是 java 集合框架中比较常用的数据结构,继承自 AbstractList。
public class Arraylist<E> extends Abstractlist<E>
ArrayList 底层是基于数组来实现容量大小动态变化的。
transient 0bject[] elementData;
因为数组是定长的,长度是一开始就要定义好的,所以为了更好简单灵活使用ArrayList就需要扩容。
扩容方式包括了两点,一类是无参构造方法,一类是有参构造方法。
无参构造方法
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
将内部数组初始化长度为0的空数组DEFAULTCAPACITY_EMPTY_ELEMENTDATA。在无参构造方法的基础之上,当第一次添加元素时,因为它是空的数组,一个存储单元都没有,所以将它的数组容量扩容为10。注:只有它初始化一个空数组,它的第一次扩容才为10。当添加使用超过10个存储单元,容量不够用时,调用grow方法计算出newcapacity,是对现有容量进行1.5倍计算。另外:数组的最大容量是在Integer.MAX_VALUE-8到Integer.MAX_VALUE之间,如果超出,则抛出OutOfMemoryError(内存不足)错误。
grow方法
private void grow(int minCapacity) {
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
elementData = Arrays.copyOf(elementData, newCapacity);
}
有参构造方法
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}
按照指定容量initialCapacity进行数组初始化。
扩容方法是当前方法灵活的体现,但是也要注意减少扩容,避免资源浪费。