ArrayList有三个构造器,分别是无参构造器,传入一个整形参数的构造器,以及传入一个Collection实例的构造器。本文主要介绍前两种构造器。
无参构造器
示例代码:
1 2 3 4 5 6 7 8 9
| public class ArrayListTest { public static void main(String[] args) { List<String> strings = new ArrayList<>(); strings.add("abc"); } }
|
下面看调用构造器以及添加元素的代码
1 2 3 4 5 6 7
| * 用初始的10的容量大小构造一个空的list */ public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; }
|
从上述构造器可以看出,无参构造器只是很简单将常量DEFAULTCAPACITY_EMPTY_ELEMENTDATA赋给成员变量elementData。这个成员变量和常量如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| * Shared empty array instance used for default sized empty instances. We * distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when * first element is added. */ private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; * The array buffer into which the elements of the ArrayList are stored. * The capacity of the ArrayList is the length of this array buffer. Any * empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA * will be expanded to DEFAULT_CAPACITY when the first element is added. */ transient Object[] elementData;
|
从注释可以看出,DEFAULTCAPACITY_EMPTY_ELEMENTDATA是一个空的数组实例,用来作为默认大小的空List。它与EMPTY_ELEMENTDATA同时存在,是为了当第一个元素被添加到list中时,能算出要扩展多大的容量。
elementData是ArrayList中用于实际存储元素的数组。一个ArrayList实例的容量就是这个数组的长度。任何调用了默认构造器生成的ArrayList实例,都执行了elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA,当第一个元素被添加到list中时,都会被扩展到默认的容量大小,即DEFAULT_CAPACITY(10)。
末尾添加元素的函数:
1 2 3 4 5 6 7 8 9 10 11 12 13
| * Appends the specified element to the end of this list. * * @param e element to be appended to this list * @return <tt>true</tt> (as specified by {@link Collection#add}) */ public boolean add(E e) { ensureCapacityInternal(size + 1); elementData[size++] = e; return true; }
|
该方法首先调用了ensureCapacityInternal函数,用于确保容量足以添加一个元素。ensureCapacityInternal方法:
1 2 3 4 5 6 7 8 9
| private void ensureCapacityInternal(int minCapacity) { if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); } ensureExplicitCapacity(minCapacity); }
|
之后调用了ensureExplicitCapacity函数,继续扩展容量大操作:
1 2 3 4 5 6 7
| private void ensureExplicitCapacity(int minCapacity) { modCount++; if (minCapacity - elementData.length > 0) grow(minCapacity); }
|
上述方法继续调用grow函数,完成扩容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| * Increases the capacity to ensure that it can hold at least the * number of elements specified by the minimum capacity argument. * * @param minCapacity the desired minimum capacity */ private void grow(int minCapacity) { int oldCapacity = elementData.length; int newCapacity = oldCapacity + (oldCapacity >> 1); if (newCapacity - minCapacity < 0) newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); elementData = Arrays.copyOf(elementData, newCapacity); }
|
从注释可知,该方法增长容量以确保list至少能保存传入参数大小数量多元素。之后,就可以插入元素“abc”。插入之后,list的size为1,容量为10.