ArrayList扩容机制分析

问题

在ArrayList中,每次调用添加元素的函数时候,总归要调用ensureCapacity。
保证着底层的数组永远不会到头,今天我们就来探究一下Java的这个函数扩容机制到底是什么样。

ensureCapacityInternal

例如add之流,最先调用的是ensureCapacityInternal( this.size + 1),表示至少需要当前容量加一的数组大小,这是无可厚非的。
但细看其中操作,有让人有些迷惑。

if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
	minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}

冒出几个新的值,我们来看一看它们的真面目吧。

变量意思数值
DEFAULTCAPACITY_EMPTY_ELEMENTDATA默认大小空实例的共享空数组{ }
DEFAULT_CAPACITY默认初始容量大小10
MAX_ARRAY_SIZE最大长度Integer.MAX_VALUE - 8

这下恍然大悟,如果当前list中没有存储(也就是底层是空数组),那么如果让minCapacity保持为1,未免消耗了性能,故而多给数组分配点儿。

ensureExplicitCapacity

经过第一道检测是否为空数组处理(判断最小扩容)之后。我们进入了这个函数(判断是否需要扩容)。

modCount++;
if (minCapacity - elementData.length > 0)
	grow(minCapacity);

当数组长度已经无法满足我们所需要的最小扩容,那么我们必将grow()。

grow

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);
  1. 首先,新的容量变成旧容量1.5倍。
  2. 如果新容量还是无法满足需求,那么就设置为最小需求容量。
  3. 调用copyOf(这个函数就像是专门为数组增长量身定做)
  4. 如果超过了数组的最大限制,就要进行处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值