java ArrayList 的默认大小

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/35268532/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 23:55:55  来源:igfitidea点击:

Default size of ArrayList

javaarraysarraylist

提问by Dedyshka

Looking through some piece of code I noticed one strange initialization of ArrayList:

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

... = new ArrayList<..>(0);

I've opened JavaSE 7sources and saw that inner elementData arrray is initialized by empty array constant - {}. When we pass capacity to the ArrayListconstructor we do almost the same - new Object[0]. So my question is: is there is any difference between new ArrayList(0)and new ArrayList()? Shouldn't ArrayListset the default capacity size to smth like 10 ?

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

Thanks all for answers.

谢谢大家的回答。

采纳答案by wero

An ArrayListhas an internal array to store the list elements.

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

There is a difference between the two constructor calls in Java 7 and 8:

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

If you do new ArrayList<>(0)the ArrayListcreates a new Object array of size 0.

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

If you do new ArrayList<>()the ArrayListuses a static empty Object array of size 0 and switches to an own private array once you add items to the list.

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

EDIT:

编辑:

The Javadoc of the default ArrayListconstructor seems to contradict this.

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

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

But it does not create an element array of length 10 immediately, but instead when you add elements or ensure the capacity:

但它不会立即创建长度为 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);
    }
}

回答by Jesus Zavarce

It is necessary to clarify two definitions:

有必要澄清两个定义:

The sizerepresent the number of elements in the list.

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

The capacityrepresent the length of the internal array. In other words, the length contains the number of places to put an element;

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

Exemple of the length of an arraylist size = 2

数组长度示例列表大小 = 2

When you create one list with the default constructor of Arraylist:

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

Ex:

前任:

List<String> list = new ArrayList<>();
System.out.println(l.size());

The output is : 0

输出为:0

Why?

为什么?

Because the list is empty, this is explained by the internal array of the list, when you use the default constructor of ArrayList, the internal array is :

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

private static final Object[] EMPTY_ELEMENTDATA = {}; 

So, an empty array of Objects where the value of the length is 0 (Capacity). As the list is empty the size is 0.

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

state of the list when the default constructor is used(id of elementData=27)

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

When you add one element to the list, the size of your list is incremented to 1, and the initial internal array of your list is changed by another array with a length of 10 (capacity);(id of elementData=30)

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

private static final int DEFAULT_CAPACITY = 10

State of the list after add one element(id of elementData=30)

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

About the default constructor of ArrayList, the API java says : API Java : https://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html#ArrayList%28%29

关于 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.

In other words, this constructor create an empty list (size equals to 0) with an initial capacity of ten elements.(After add one element to the list, the capacity of the list become 10)

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

When you know the size of your list, you should create your list with this size. Why? because the complexity of the method add (E element)is O(1) amortized (when there is available space in your list), but O(n) (worst-case) if you add more elements than the initial capacity of your list, in this case, a new array (1.5 times the size) is allocated, and the old array is copied to the new one. Clearly, this operation has costs in terms of performance and memory resources.

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

So, create a list with an initial capacity of 0 has no sense. If you don't know the initial capacity of your list, use the default constructor that give to you one list with an initial capacity of ten elements.

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

Keep in mind that definitions of size and capacity around ArrayList are differents:

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

From book Core Java 2: Fundamentals

来自 Core Java 2: Fundamentals 一书

Allocating an array list as new ArrayList <'Employee>(100) // capacity is 100

is not the same as allocating a new array as new Employee[100] // size is 100

There is an important distinction between the capacity of an array list and the size of an array. If you allocate an array with 100 entries, then the array has 100 slots, ready for use. An array list with a capacity of 100 elements has the potential of holding 100 elements (and, in fact, more than 100, at the cost of additional reallocations); but at the beginning, even after its initial construction, an array list holds no elements at all.

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

与将新数组分配为 new Employee[100] 不同 // 大小为 100

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

回答by Gavriel

ArrayList has 2 constructors. The default constructor just calls the other one with capacity=10:

ArrayList 有 2 个构造函数。默认构造函数只调用另一个容量为 10 的构造函数:

ArrayList() {this(10);}

ArrayList(capacity)

What capacity means? It means that an array of the size capacity is allocated to hold the items in the arraylist. Whenever it's too small to hold the necessary items, it's being resized, by creating a bigger array and copying everything over (takes time) + it means the old array needs to be garbage collected (even more time). That's why it is important to get the correct capacity right. Although it will work with any initial capacity, it can be slow. On the other hand having huge capacity and almost no items in it is wasting memory.

容量是什么意思?这意味着分配了一个容量大小的数组来保存数组列表中的项目。每当它太小而无法容纳必要的项目时,就会通过创建更大的数组并复制所有内容(需要时间)来调整其大小+这意味着旧数组需要被垃圾收集(甚至更多时间)。这就是为什么获得正确的容量很重要的原因。尽管它可以在任何初始容量下工作,但它可能会很慢。另一方面,容量巨大且几乎没有项目是浪费内存。

Note: Arraylist(0) will create a 0 size array, and when you try to add the 1st element, it'll be thrown away and a new array allocated.

注意:Arraylist(0) 将创建一个 0 大小的数组,当您尝试添加第一个元素时,它将被丢弃并分配一个新数组。

回答by Ruslanas

ArrayList() will make list capacity of 10 (default) after first element added. However ArrayList(0) will keep capacity small - it will be 1 after first element added, 2 after the second add, and etc.

添加第一个元素后,ArrayList() 将使列表容量为 10(默认)。但是 ArrayList(0) 将保持较小的容量 - 添加第一个元素后为 1,添加第二个元素后为 2,依此类推。