以无参构造为例
第一步:调用add方法添加元素
public boolean add(E e) { ensureCapacityInternal(size + 1); // 添加元素前先调用ensureCapacityInternal方法 elementData[size++] = e;//添加对象时,size+1 return true; }
第二步:调用ensureCapacityInternal方法,设定好minCapacity的值
private void ensureCapacityInternal(int minCapacity) { if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { //判断是否为空数组 minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); } ensureExplicitCapacity(minCapacity); }
当空数组添加第1个元素时,minCapacity=1,调用max()方法取出DEFAULT_CAPACITY和minCapacity的最大值 ,minCapacity变为DEFAULT_CAPACITY(默认大小10),调用ensureExplicitCapacity方法。
当添加第2个元素时,直接调用ensureExplicitCapacity方法。
第三步:调用ensureExplicitCapacity方法修改修改次数,并判断是否需要扩容
private void ensureExplicitCapacity(int minCapacity) { modCount++;//修改次数加1 // overflow-conscious code if (minCapacity - elementData.length > 0) grow(minCapacity);//调用扩容方法 }
当添加第1个元素时,此时的elementData.length=1(为空列表),minCapacity=10,所以minCapacity>elementData.length,会进入grow(minCapacity)方法(此时minCapacity=10)。
当添加第2个元素时,此时的minCapacity=2,此时elementData.length(即是容量)在添加第一个元素后扩容成10了,所以minCapacity<elementData.length,不会进入grow(minCapacity)方法,数组容量仍为10不变
所以当添加第3、4···到第10个元素时,依然不会执行grow方法,数组容量都为10。
当添加到第11个元素时,(minCapacity=11)>(elementData.length=10),所以进入grow(minCapacity)方法进行扩容。
第四步:调用grow方法进行扩容
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
private void grow(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length; //通过位运算右移一位,相当于除以2,运算速度快,新容量扩大到原容量的1.5倍 int newCapacity = oldCapacity + (oldCapacity >> 1); if (newCapacity - minCapacity < 0) //从minCapacity和newCapacity种取出一个较大值作为扩容后新数组的容量 //这个if判断主要是针对添加第一个元素时使用,1.5倍的oldCapacity 还是为0,所以newCapacity为最小容量10 newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0) //如果新容量大于数组的最大size,进入hugeCapacity方法 newCapacity = hugeCapacity(minCapacity); // minCapacity is usually close to size, so this is a win: //最后将原来的数组和新的容量大小传入到copyOf方法中复制(先设定一个新容量大小的数组,把原数据放入其中即可) elementData = Arrays.copyOf(elementData, newCapacity); }
当add第1个元素时,oldCapacity为0,第一个if成立,newCapacity=minCapacity=10;但是第二个if不成立,则不会进入hugeCapacity方法,数组容量为10,add方法中return true,size增为1。
当add第11个元素进入grow方法时,newCapacity为15,比minCapacity(为11)大,第一个if判断不成立。新容量没有大于数组最大size,不会进入hugeCapacity方法。数组容量扩为15,add方法中return true,size增为11。
第五步:如果新容量大于MAX_ARRAY_SIZE,进入hugeCapacity方法
private static int hugeCapacity(int minCapacity) { if (minCapacity < 0) // overflow throw new OutOfMemoryError(); return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; }