大家好,又见面了,我是你们的朋友全栈君。
ArrayList大家都知道了吧,这是一个动态数组。以java语言来说,数组是定长的,在被创建之后就不能被加长或缩短了,因此,了解它的扩容机制对使用它尤为重要。下面,我们就一起来看看它的扩容机制是怎么实现的吧。
首先我们知道,ArrayList有着三种初始化方式:
1)指定大小初始化public ArrayList(int initialCapacity)
2)传入一个Collection对象初始化,并将对象中的数据添加到ArrayList中public ArrayList(Collection c)
3)默认构造函数初始化public ArrayList()
ArrayList扩容机制发生在add()方法调用的时候,从下面的代码我们可以看出当使用无参构造函数创建ArrayList时,它的默认长度会为0private 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
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常见问答知识,就快来关注我们的网站吧。
推荐阅读:
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/143995.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...