【2021-07-01】初始化一个空的 ArrayList,此时底层数组的容量为多少?添加一个元素后,容量为多少?
请移步至:
每日一题 查看更多的题目 ~
答:
初始化一个空的 ArrayList ,此时底层数组的容量为 0,添加一个元素后,底层数组的容量为 10。
在 ArrayList 中,存储数据的底层是一个可支持动态扩容的数组 elementData:
transient Object[] elementData; // non-private to simplify nested class access
首先,我们通过反射,获取到 elementData 字段,来验证下我们的答案是否正确:
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
ArrayList<Integer> list = new ArrayList<>();
System.out.println("elementData length : " + getArrayListElementDataLength(list));
list.add(1);
System.out.println("elementData length : " + getArrayListElementDataLength(list));
}
private static int getArrayListElementDataLength(ArrayList list) throws NoSuchFieldException, IllegalAccessException {
Class<? extends List> listClass = list.getClass();
Field field = listClass.getDeclaredField("elementData");
field.setAccessible(true);
Object[] elementData = (Object[]) field.get(list);
return elementData.length;
}
}
程序运行,输出结果为:
elementData length : 0
elementData length : 10
原因解释:
首先,我们来看下 ArrayList 的无参构造器:
/**
* Constructs an empty list with an initial capacity of ten.
*/
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
当我们初始化一个没有指定容量大小的 ArrayList 时,构造器只是将 elementData 赋值给了一个空数组。
我们来看下 ArrayList 的 add 方法:
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
private void ensureCapacityInternal(int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
我们看到,每次向 ArrayList 添加元素时,都会执行一个 ensureCapacityInternal 方法,该方法用来保证每次向 ArrayList 中添加元素时,底层数组 elementData 容量是足够的,进入到该方法,我们看到第一行代码会执行一个判断语句:
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
当 elementData 数组为空,就会将 minCapacity 赋值给 DEFAULT_CAPACITY (10) 和 minCapacity 较大的那一个;添加一个元素,minCapacity 为 1,而 DEFAULT_CAPACITY 为 10;
/**
* Default initial capacity.
*/
private static final int DEFAULT_CAPACITY = 10;
所以,一个空的 ArrayList 在第一次添加元素后,底层的 elementData 就会变为一个长度为 10 的数组。