add方法
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
// 添加元素
public boolean add(E e) {
ensureCapacityInternal(size + 1); // 确保数组容量足够添加
elementData[size++] = e;
return true;
}
调用add方法往ArrayList中添加元素时,整体分为两个步骤:1、确保有足够的容量;2、把元素添加进去;所以这里的重点就是第一步了。
// 确认内置容量
private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
// 计算容量
private static int calculateCapacity(Object[] elementData, int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
return minCapacity;
}
ensureCapacityInternal方法又分为两步,1、计算容量;2、确保容量足够;
calculateCapacity计算容量,如果是调用了ArrayList的无参构造方法的话,使用的就是DEFAULTCAPACITY_EMPTY_ELEMENTDATA,所以就会拿默认容量DEFAULT_CAPACITY和传进来的minCapacity进行比较,选择较大值作为新容量。
如果创建ArrayList时传入了容量,那么这里就是数组容量加1了。
// 确保显示容量
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
ensureExplicitCapacity方法中首先执行了一个modCount++,这个的目的是防止并发修改,数组容量每次发生修改都要修改这个值,然后和expectedModCount进行比较,如果不一致就会触发异常。
先判断一下数组现在的容量是否小于需要的容量,如果是的会就需要扩容了,否则容量足够就不用执行操作,直接把数据存进去就行了。
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length; // 获取现在的容量
int newCapacity = oldCapacity + (oldCapacity >> 1); // 扩容 变为1.5倍
if (newCapacity - minCapacity < 0) // 新容量还是不够
newCapacity = minCapacity; // 那就把容量设为新容量
if (newCapacity - MAX_ARRAY_SIZE > 0) // 如果容量超过了最大容量
newCapacity = hugeCapacity(minCapacity); //
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
标签:容量,int,ArrayList,elementData,newCapacity,minCapacity,源码
From: https://www.cnblogs.com/bright1st/p/17596150.html