ArrayList:线程不安全,内部使用一个数组实现
transient Object[] elementData; // non-private to simplify nested class access
无参构造函数源码:
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
//...DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}
//说明ArrayList使用无参构造时,初始内部为空数组。
调用add方法添加元素
ArrayList进行add操作时,会获取一个"最小数组容量",
(如果此时数组为空数组,最小数组容量为10,否则为当前元素个数加一)
然后将最小容量与当前数组长度比较,以判断是否需要扩容。
最后再进行赋值操作
add(E)方法:
ensureCapacityInternal(size + 1);
elementData[size++] = e;
//注意size+1临时赋值给了minCapacity。
//这个minCapacity将会多次出现,意为最小数组容量
进入ensureCapacityInternal(int minCapacity)方法:
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
//elementData:{},minCapacity:1
//在这个方法里调用了两个方法:分别是calculateCapacity方法(返回最小数组容量)
ensureExplicitCapacity方法(判断是否扩容)
进入calculateCapacity(Object[] elementData, int minCapacity)方法(这个方法主要作用是返回最小数组容量):
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
return minCapacity;
//判断内部数组是不是空数组
//是的话返回DEFAULT_CAPACITY:10和minCapacity:1的较大者->10
//不是的话直接返回minCapacity->当前元素个数加一
此时返回到了ensureCapacityInternal方法中,获取到了最小数组容量,接着调用ensureExplicitCapacity方法以判断数组是否进行扩容
ensureExplicitCapacity(int minCapacity)方法( 判断数组是否扩容)
modCount++;//元素个数加一
if (minCapacity - elementData.length > 0)
//如果minCapacity(最小数组容量)大于当前数组长度(if成立),那么进行扩容
grow(minCapacity)
grow(int minCapacity)方法(扩容)
int oldCapacity = elementData.length;
//旧容量为数组长度。空数组情况下即为0
int newCapacity = oldCapacity + (oldCapacity >> 1);
//新容量为旧容量的1.5倍。空数组情况下也为0,因为0*1.5=0
if (newCapacity - minCapacity < 0)
//新容量小于数组最小容量时,将新容量重新赋值为数组最小容量。
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
//扩容
elementData = Arrays.copyOf(elementData, newCapacity);
grow方法执行完后会回到add方法,最后才执行元素的赋值操作
elementData[size++] = e;
概括:
使用无参构造函数初始化ArrayList时,内部数组为空数组。
ArrayList进行add操作时,会先获取一个最小数组容量(上面的minCapacity)。
如果此时数组为空数组,最小数组容量为10,否则就为当前元素个数加一。
return Math.max(DEFAULT_CAPACITY, minCapacity);
紧接着进行一次判断:
if (minCapacity - elementData.length > 0)
//如果当前数组长度大于最小数组容量(无需扩容),那么直接添加元素。
//如果当前数组长度小于最小数组容量,那么就会进行数组的扩容(grow)。
扩容时需要一个新容量(newCapacity),新容量为旧容量(oldCapacity)的1.5倍。
int newCapacity = oldCapacity + (oldCapacity >> 1);
但是如果此时为空数组的话,那么新容量也为0。因为旧容量为0,而0*1.5=0。
所以会进行一次判断,新容量小于最小长度时,将新容量重新赋值为最小容量。
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
最后再使用这个新容量对数组进行扩容。扩容完毕后,最后再进行元素的赋值。
elementData = Arrays.copyOf(elementData, newCapacity);
...
elementData[size++] = e;