ArrayList的默认大小

Ded*_*hka 6 java arrays arraylist

通过一些代码,我注意到一个奇怪的ArrayList初始化:

... = new ArrayList<..>(0);
Run Code Online (Sandbox Code Playgroud)

我打开了JavaSE 7源代码,看到内部elementData arrray由空数组常量初始化 - {}.当我们将容量传递给ArrayList构造函数时,我们几乎一样 - new Object[0].所以我的问题是:新的ArrayList(0)new ArrayList()?之间有什么区别吗?不应该ArrayList将默认容量大小设置为像10一样?

谢谢大家的回答.

Jes*_*rce 7

有必要澄清两个定义:

大小 表示列表中的元素的数量.

容量表示内部阵列的长度.换句话说,长度包含放置元素的位置数;

例如数组的长度 列表大小= 2

使用Arraylist的默认构造函数创建一个列表时:

例如:

List<String> list = new ArrayList<>();
System.out.println(l.size());
Run Code Online (Sandbox Code Playgroud)

输出为:0

为什么?

因为列表是空的,所以列表的内部数组解释了这一点,当你使用ArrayList的默认构造函数时,内部数组是:

private static final Object[] EMPTY_ELEMENTDATA = {}; 
Run Code Online (Sandbox Code Playgroud)

因此,一个空数组的对象,其中长度的值为0(容量).由于列表为空,因此大小为0.

使用默认构造函数时的列表状态 (elementData = 27的id)

向列表中添加一个元素时,列表的大小将增加到1,列表的初始内部数组将被另一个长度为10(容量)的数组更改; (elementData = 30的id)

private static final int DEFAULT_CAPACITY = 10
Run Code Online (Sandbox Code Playgroud)

添加一个元素后的列表状态 (elementData = 30的id)

关于ArrayList的默认构造函数,API java说:API Java:https://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html#ArrayList%28%29

public ArrayList()

Constructs an empty list with an initial capacity of ten.
Run Code Online (Sandbox Code Playgroud)

换句话说,这个构造函数创建一个空列表(大小等于0),初始容量为10个元素.(在列表中添加一个元素后,列表的容量变为10)

当您知道列表的大小时,您应该使用此大小创建列表.为什么?因为该方法的复杂性add (E element)是O(1)摊销(当列表中有可用空间时),但是O(n)(最坏情况)如果添加的元素多于列表的初始容量,在这种情况下,分配一个新数组(大小的1.5倍),并将旧数组复制到新数组.显然,该操作在性能和存储器资源方面具有成本.

因此,创建一个初始容量为0的列表是没有意义的.如果您不知道列表的初始容量,请使用默认构造函数,该构造函数为您提供一个初始容量为10个元素的列表.

请记住,ArrayList周围的大小和容量定义是不同的:

从书籍Core Java 2:Fundamentals

将数组列表分配为新的ArrayList <'Employee>(100)//容量为100

与新员工[100] //大小为100时分配新数组不同

数组列表的容量与数组的大小之间存在重要区别.如果您分配一个包含100个条目的数组,则该阵列有100个插槽,可供使用.容量为100个元素的数组列表有可能容纳100个元素(实际上,超过100个,以额外的重新分配为代价); 但是在开始时,即使在初始构造之后,数组列表也根本不包含任何元素.


wer*_*ero 4

AnArrayList有一个内部数组来存储列表元素。

Java 7 和 8 中的两个构造函数调用之间存在差异:

如果这样做,new ArrayList<>(0)则会ArrayList创建一个大小为 0 的新对象数组。

如果您这样做,new ArrayList<>()ArrayList使用大小为 0 的静态空对象数组,并在将项目添加到列表后切换到自己的私有数组。

编辑:

默认构造函数的 JavadocArrayList似乎与此相矛盾。

/**
 * Constructs an empty list with an initial capacity of ten.
 */
public ArrayList() {
    super();
    this.elementData = EMPTY_DEFAULTCAPACITY_EMPTY_ELEMENTDATA; // = static, empty
}
Run Code Online (Sandbox Code Playgroud)

但它不会立即创建长度为10的元素数组,而是在添加元素或确保容量时:

public void ensureCapacity(int minCapacity) {
    int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
        // any size if not default element table
        ? 0
        // larger than default for default empty table. It's already
        // supposed to be at default size.
        : DEFAULT_CAPACITY; // = 10

    if (minCapacity > minExpand) {
        ensureExplicitCapacity(minCapacity);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • @Gavriel 是的,这就是情况 1。在情况 2 中,它使用静态的“DEFAULTCAPACITY_EMPTY_ELEMENTDATA”(查看源代码)。尽管添加物品或确保容量时,容量增量可能会有所不同。 (2认同)