ArrayList里面有属性是用来存放元素的
transient Object[] elementData;
调用无惨构造方法时,把一个空数组给我elementData
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
DEFAULTCAPACITY_EMPTY_ELEMENTDATA是个空数组
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
有参构造方法
当传入大小大于0时,就把内部数组初始化为传入的大小
当传入大小等于0时,就把内部数组初始化为EMPTY_ELEMENTDATA(是一个空数组)
当是负数等时,报异常
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);
}
}
添加元素add()
public boolean add(E e) {
// 传入的是size +1,size是集合中元素的个数
ensureCapacityInternal(size + 1); // Increments modCount!!
// 把元素添加到数组第size的位置(size是数组的数组中元素个数)再给size加1
elementData[size++] = e;
return true;
}
进入ensureCapacityInternal()
private void ensureCapacityInternal(int minCapacity) {
// 先调用calculateCapacity(),再调用ensureExplicitCapacity()
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
查看calculateCapaccity(),传入装元素的数组和size+1(minCapacity)
private static int calculateCapacity(Object[] elementData, int minCapacity) {
// 如果现在数组的空的,返回DEFAULT_CAPACITY(是10)和minCapacity(size+1)的最大值
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
// 如果现在的数组不是空的,返回minCapacity(size+1)
return minCapacity;
}
进入ensureExplicitCapacity()方法
private void ensureExplicitCapacity(int minCapacity) {
// 将修改记录次数+1,该变量主要是用来实现fail-fast机制的
modCount++;
// overflow-conscious code
// 判断是否需要扩容,若minCapacity比数组可容纳个数大,就要扩容
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
再调用grow()
private void grow(int minCapacity) {
// overflow-conscious code
// 数组旧容量
int oldCapacity = elementData.length;
// newCapacity = 数组旧容量 + 数组旧容量>>1(偶数除以2,基数减1除以2)
int newCapacity = oldCapacity + (oldCapacity >> 1);
// 如果newCapacity<minCapacity , 就使用minCapacity,例如,第一次add就会这样
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
// 如果newCapacity > MAX_ARRAY_SIZE(Integr的最大值减8 ,调用hugeCapacity()
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);
}
最后调用Arrays.copyOf()对数组进行扩容
hugeCapacity()
如果minCapacity大于Integer最大值-8,就取Integer的最大值,要不然就取Integer最大值-8
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
ensureCapacityInternal()方法 传入的是size +1
如果是数组是空的, 就创建一个大小是10的数组(DEFAULT_CAPACITY是10)
如果数组不是空的就调用ensureExplicitCapacity()
总结
无参构造,初始容量是0
有参构造,会先初始化内部数组的大小
调用add(),如果是第一次添加,数组是空的,就数组的大小是10
若不是空的,就是zise+1,返回一个值minCapacity
newCapacity = 先把之前的数组的容量 + 之前的数组容量>>1(偶数除以1,基数减1除以2) ---相当于1.5倍
再取minCapacity和newCapacity的最大值赋值给newCapacity
再调用grow()
newCapacity = 先把之前的数组的容量 + 之前的数组容量>>1(偶数除以1,基数减1除以2)
再取minCapacity和newCapacity的最大值赋值给newCapacity
若newCapacity > MAX_ARRAY_SIZE(Integr的最大值减8 ,调用hugeCapacity()
如果minCapacity大于Integer最大值-8,就取Integer的最大值,要不然就取Integer最大值-8
最后调用Arrays.copyOf()对数组进行扩容,生成的新的数组赋值给数组属性