先来看一下ArrayList初始化的元素个数
先看ArrayyList的构造方法,先看无参构造函数
/**
* Constructs an empty list with an initial capacity of ten.
*构造一个初始容量为10的空列表。
*/
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
这个是无参数的构造函数,给ArrayList的elementData(元素的数组)进行赋值DEFAULTCAPACITY_EMPTY_ELEMENTDATA(按道理来说这句英文的意思是空数组的意思,但是注释说了是创建容量为10的List,不管了,先看着吧)。
这个是有参数的构造函数
/**
* 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
*构造具有指定初始容量的空列表。如果initialCapacity为负的话,那么抛出异常
*/
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
//构造具有指定初始容量的空列表。如果initialCapacity为负的话,那么抛出异常
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}
再看另一个构造函数
/**
* Constructs a list containing the elements of the specified
* collection, in the order they are returned by the collection's
* iterator.
*按照指定集合的迭代器返回的顺序,构造一个包含指定集合元素的列表。
* @param c the collection whose elements are to be placed into this list
* @throws NullPointerException if the specified collection is null
*/
public ArrayList(Collection<? extends E> c) {
//使用 toArray 方法将集合 c 转换为数组,并将其赋值给 elementData。elementData 是 ArrayList 内部用于存储元素的数组。
elementData = c.toArray();
if ((size = elementData.length) != 0) {
// c.toArray might (incorrectly) not return Object[] (see 6260652)
//判断 elementData 所属的类是否不是 Object[] 类型。
if (elementData.getClass() != Object[].class)
//如果 elementData 不是 Object[] 类型,通过 Arrays.copyOf 将其转换为 Object[] 类型。这个步骤的目的是确保 elementData 是 Object[] 类型的数组。
elementData = Arrays.copyOf(elementData, size, Object[].class);
} else {
//如果 elementData 的长度为 0,则执行下面的逻辑。
// replace with empty array.
//将 elementData 设置为 ArrayList 内部定义的空数组 EMPTY_ELEMENTDATA。这个数组在 ArrayList 类中是一个静态常量,表示一个空的数组实例。
this.elementData = EMPTY_ELEMENTDATA;
}
}
然后来看一下add()方法
public boolean add(E e) {
//就是ensureCapacitylnternal(size + 1)并且将e添加到size++的位置,我们来看ensureCapacitylnternal(size + 1)方法。
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
private void ensureCapacityInternal(int minCapacity) {
//DEFAULTCAPACITY_EMPTY_ELEMENTDATA看着是不是很眼熟,它就是空构造函数赋的值
//所以这个时候minCapacity其实是为0,所以其实就是DEFAULT_CAPACITY数值为10
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
然后再看ensureExplicitCapacity(minCapacity);
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
//检查当前容量是否小于指定的最小容量(minCapacity)。如果是,说明需要进行扩容。
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
接下来看看grow(minCapacity);方法
private void grow(int minCapacity) {
// overflow-conscious code
//获取当前 ArrayList 内部数组的长度,即当前容量。
int oldCapacity = elementData.length;
//计算新的容量,通过将当前容量右移一位并加上原始容量,相当于将容量扩大 1.5 倍。
int newCapacity = oldCapacity + (oldCapacity >> 1);
//检查计算得到的新容量是否小于所需的最小容量(即 minCapacity)。如果是,将新容量设置为最小容量。
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
//检查新容量是否超过了数组的最大容量(MAX_ARRAY_SIZE)。如果是,调用 hugeCapacity 方法来计算新容量,确保它不超过 MAX_ARRAY_SIZE。
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
//使用 Arrays.copyOf 方法将内部数组 elementData 扩容到新的容量 newCapacity。这个操作会创建一个新的数组,并将旧数组的元素复制到新数组中。
elementData = Arrays.copyOf(elementData, newCapacity);
}
最后总结一下:无参构造方法调用add之后创建的是10个长度的数组。有参数则直接创建指定长度的数组.。扩容时,小于MAX ARRAY_SIZE = lnteger,MAX VALUE-8 次扩容1.5 倍,超过则直接Integer.MAX VALUE.