ArrayList大家都知道了吧,这是一个动态数组。以java语言来说,数组是定长的,在被创建之后就不能被加长或缩短了,因此,了解它的扩容机制对使用它尤为重要。下面,我们就一起来看看它的扩容机制是怎么实现的吧。
首先我们知道,ArrayList有着三种初始化方式:
1)指定大小初始化
public ArrayList(int initialCapacity)
2)传入一个Collection对象初始化,并将对象中的数据添加到ArrayList中
public ArrayList(Collection c)
3)默认构造函数初始化
public ArrayList()
ArrayList扩容机制发生在add()方法调用的时候,从下面的代码我们可以看出当使用无参构造函数创建ArrayList时,它的默认长度会为0
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; }
下面是add()方法的源码:
public boolean add(E e) { //扩容 ensureCapacityInternal(size + 1); // Increments modCount!! elementData[size++] = e; return true; }
根据以上我们可以看到,ensureCapacityInternal()是用来扩容的,形参为最小扩容量,进入此方法后:
private void ensureCapacityInternal(int minCapacity) { ensureExplicitCapacity(calculateCapacity(elementData, minCapacity)); }
通过方法calculateCapacity(elementData, minCapacity)来获取:
private static int calculateCapacity(Object[] elementData, int minCapacity) { //如果传入的是个空数组则最小容量取默认容量与minCapacity之间的最大值 if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { return Math.max(DEFAULT_CAPACITY, minCapacity); } return minCapacity; } ensureExplicitCapacity方法可以判断是否需要扩容: private void ensureExplicitCapacity(int minCapacity) { modCount++; // 如果最小需要空间比elementData的内存空间要大,则需要扩容 if (minCapacity - elementData.length > 0) //扩容 grow(minCapacity); }
下面是重点来了,ArrayList扩容机制关键方法grow():
private void grow(int minCapacity) { // 获取到ArrayList中elementData数组的内存空间长度 int oldCapacity = elementData.length; // 扩容至原来的1.5倍 int newCapacity = oldCapacity + (oldCapacity >> 1); // 再判断一下新数组的容量够不够,够了就直接使用这个长度创建新数组, // 不够就将数组长度设置为需要的长度 if (newCapacity - minCapacity < 0) newCapacity = minCapacity; //若预设值大于默认的最大值检查是否溢出 if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); // 调用Arrays.copyOf方法将elementData数组指向新的内存空间时newCapacity的连续空间 // 并将elementData的数据复制到新的内存空间 elementData = Arrays.copyOf(elementData, newCapacity); }
因此,我们可以清晰看出ArrayList扩容的本质其实就是计算出新的扩容数组的size后实例化它,并将原有数组内容复制到新数组中去。
以上就是关于ArrayList扩容机制的全部内容了,如果你还想要了解更多有关ArrayList相关的java常见问答知识,就快来关注我们的网站吧。
推荐阅读: