【2021-07-01】初始化一个空的 ArrayList,此时底层数组的容量为多少?添加一个元素后,容量为多少?

未匹配的标注

请移步至::octocat:每日一题 查看更多的题目 ~

答:

初始化一个空的 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 的数组。

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
讨论数量: 0
发起讨论 只看当前版本


暂无话题~