ArrayList有三个构造方法
1.ArrayList()
ArrayList arrayList = new ArrayList();
分析:
/** * Constructs an empty list with an initial capacity of ten.创建空集合,初始容量10 * transient Object[] elementData;集合存元素的变量 * private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};默认空容量对象 */ public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; }
//调用空构造器的时候,会将elementData赋值为空对象数组。
//此时添加元素,调用add(E e)方法。
public boolean add(E e) { ensureCapacityInternal(size + 1); // Increments modCount!! elementData[size++] = e; return true; }
//添加元素之前会确认容量,调用ensureCapacityInternal方法
private void ensureCapacityInternal(int minCapacity) { ensureExplicitCapacity(calculateCapacity(elementData, minCapacity)); }
//第一次调用的时候,minCapacity = size + 1 (size第一次添加时为0,因此minCapacity = 0 + 1 = 1)
//调用此方法calculateCapacity(elementData, minCapacity)
//该方法计算最小容量值
private static int calculateCapacity(Object[] elementData, int minCapacity) { if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {//第一次添加时,满足条件 return Math.max(DEFAULT_CAPACITY, minCapacity);//得到最小容量,即minCapacity = 10 } return minCapacity; }
//ensureExplicitCapacity(10),这里的参数为上一步计算得到的最小容量值10
private void ensureExplicitCapacity(int minCapacity) { modCount++;//记录修改次数,主要用于多线程 provide fail-fast iterators // overflow-conscious code if (minCapacity - elementData.length > 0) //此时,elementData.length第一次添加时为0 grow(minCapacity); //进行扩容 }
//此方法为真正扩容方法,此时 minCapacity = 10
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length; //记录旧集合的元素个数,此时为0
//在旧容量的基础上,扩容1.5倍(右移1位相当于/2)
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0) //第一次的时候集合元素为空,newCapacity = 0,
newCapacity = minCapacity; //newCapacity = 10 第一次扩容,容量为10
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); //进行数组拷贝,扩容为10
}
//扩容完成以后,容量为10,第一个元素被添加进去
//此后继续添加元素时,重复以上方法,在添加的元素数量未达到容量10时,不会进行扩容操作
//即以下判断不成立
if (minCapacity - elementData.length > 0) grow(minCapacity);
//直到添加第11个元素,即添加的数量超过当前集合的容量时,该if判断条件成立,进入grow(minCapacity)方法,此时minCapacity = 11
// minCapacity = 11,该方法为真正扩容方法
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: //进行扩容,将原来数组的元素拷贝到新数组,扩容为原来的1.5倍 //实际调用的扩容方法为:System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength)); elementData = Arrays.copyOf(elementData, newCapacity); }
//此后,添加的逻辑相似,当添加的元素数量又大于当前容量时扩容1.5,以此类推。
2.调用有参构造函数 ArrayList arrayList = new ArrayList(8);
分析:
/** * Constructs an empty list with the specified initial capacity. * * @param initialCapacity the initial capacity of the list * @throws IllegalArgumentException if the specified initial capacity * is negative * private static final Object[] EMPTY_ELEMENTDATA = {}; */ public ArrayList(int initialCapacity) { // initialCapacity = 8 if (initialCapacity > 0) { this.elementData = new Object[initialCapacity]; //构造一个初始容量的Object数组 } else if (initialCapacity == 0) { //如果构造函数的参数为0,则赋值为空对象数组 this.elementData = EMPTY_ELEMENTDATA; } else { throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); } }
//执行添加方法,逻辑和无参构造走的方法一模一样
//只不过调用到这里的时候elementData不是空数组,而是初始容量为构造参数值 = 8的对象数组
private static int calculateCapacity(Object[] elementData, int minCapacity) { if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { //条件不成立 return Math.max(DEFAULT_CAPACITY, minCapacity); } return minCapacity; //这里返回8 minCapacity = 8 }
//之后的逻辑与无参构造执行的添加逻辑一样,也是先确认是否需要扩容,然后再执行其他操作,只不过现在的扩容是在8(构造参数中的值)的基础上扩容1.5倍。