java 数组列表的容量和数组大小的区别

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27946920/
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 12:41:18  来源:igfitidea点击:

Distinction between the capacity of an array list and the size of an array

javaarraysarraylist

提问by Kumar V

I read the below snippet in Core Java I book.

我在我预订的 Core Java 中阅读了以下代码段。

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 个,以额外的重新分配为代价);但是在开始时,即使在其初始构造之后,数组列表也根本不包含任何元素。

When I saw the source code array list, the constructor creates of an Object array of given capacity which is ready to hold elements of given capacity (below is the code snippet).

当我看到源代码数组列表时,构造函数创建了一个给定容量的对象数组,该数组准备保存给定容量的元素(以下是代码片段)。

public ArrayList(int initialCapacity) {
     super();
     if (initialCapacity < 0)
         throw new IllegalArgumentException("Illegal Capacity: "+
                                            initialCapacity);
     this.elementData = new Object[initialCapacity];
 }

I am not able to figure out the actual difference what the author has mentioned in above text.

我无法弄清楚作者在上面的文字中提到的实际差异。

回答by RealSkeptic

If you allocate a new array with arr = new Employee[100], the size of that array (arr.length) is going to be 100. It has 100 elements. All the elements are initially null (as this is an array of object references), but still, there are 100 elements.

如果您使用 分配一个新数组arr = new Employee[100],则该数组 ( arr.length)的大小将为 100。它有 100 个元素。所有元素最初都是空的(因为这是一个对象引用数组),但仍然有 100 个元素。

If you do something like list = new ArrayList <Employee>(100), and try to check list.size(), you'll get 0. There are no elements in the list.

如果您执行类似的操作list = new ArrayList <Employee>(100)并尝试检查list.size(),您将得到 0。列表中没有元素。

Internally, it's true that the ArrayListallocates enough place to put 100 items before it needs to extend its capacity, but that's an internal implementation detail, and the list presents its content to you as "no items stored". Only if you actually do list.add(something), you'll have items in the list.

在内部,确实ArrayList在需要扩展其容量之前分配了足够的位置来放置 100 个项目,但这是一个内部实现细节,并且列表向您显示其内容为“未存储项目”。只有当你真的这样做时list.add(something),你才会在列表中看到项目。

So although the list allocates storage in advance, the API with which it communicates with the program tells you there are no items in it. The null items in its internal array are not available to you - you cannot retrieve them or change them.

因此,尽管列表预先分配了存储空间,但它与程序通信的 API 会告诉您其中没有任何项目。您无法使用其内部数组中的空项目 - 您无法检索或更改它们。

回答by James Hart

An ArrayList is just one way to represent an abstract list, and the capacity of an ArrayList is an implementation detail of how the system implements the logical list.

ArrayList 只是表示抽象列表的一种方式,ArrayList 的容量是系统如何实现逻辑列表的实现细节。

An ArrayList stores the elements of a list by using an actual array "under the covers." The actual realization of the array in computer memory has a certain size when it is allocated; this size is the ArrayList's capacity. The ArrayList emulates a variable-sized list by storing the logical length of the list in addition to the fixed-length array. Thus if you have an ArrayList with a capacity 10 which contains 4 logical elements, the ArrayList can be represented as a length and an array

ArrayList 通过使用“幕后”的实际数组来存储列表的元素。数组在计算机内存中的实际实现在分配时有一定的大小;这个大小是 ArrayList 的容量。除了固定长度的数组之外,ArrayList 还通过存储列表的逻辑长度来模拟可变大小的列表。因此,如果您有一个容量为 10 且包含 4 个逻辑元素的 ArrayList,则 ArrayList 可以表示为一个长度和一个数组

(4) | e1 | e2 | e3 | e4 | __ | __ | __| __ | __ | __ |

(4) | e1 | e2 | e3 | e4 | __ | __ | __| __ | __ | __ |

where the (4) is the logical length of the list and '__' represent data that is ignored because it is not part of the logical list. If you attempt to access the 5th element of this ArrayList, it will throw an exception because it knows that the fifth element has not been initialized. If we then append an extra element e5 to the list, the ArrayList becomes

其中 (4) 是列表的逻辑长度,'__' 表示被忽略的数据,因为它不是逻辑列表的一部分。如果您尝试访问此 ArrayList 的第 5 个元素,它将抛出异常,因为它知道第 5 个元素尚未初始化。如果我们随后将一个额外的元素 e5 附加到列表中,则 ArrayList 变为

(5) | e1 | e2 | e3 | e4 | e5 | __ | __ | __ | __ | __ |

(5) | e1 | e2 | e3 | e4 | e5 | __ | __ | __ | __ | __ |

Note that the capacity has not changed, while the logical length has, because the underlying array is still able to handle all the data in the logical list.

注意容量没有变化,而逻辑长度有变化,因为底层数组仍然能够处理逻辑列表中的所有数据。

If you manage to add more than ten elements to this list, the ArrayList will not break. The ArrayList is an abstraction meant to be compatible with all array operations. Rather, the ArrayList changes its capacity when its logical length exceeds its original capacity. If we were to add the elements (a1, a2, ..., a7) to the above list, the resulting ArrayList might look like

如果您设法向此列表添加十多个元素,则 ArrayList 不会中断。ArrayList 是一种抽象,旨在与所有数组操作兼容。相反,当 ArrayList 的逻辑长度超过其原始容量时,它会更改其容量。如果我们将元素 (a1, a2, ..., a7) 添加到上面的列表中,结果 ArrayList 可能看起来像

(12) | e1 | e2 | e3 | e4 | e5 | a1 | a2 | a3 | a4 | a5 | a6 | a7 | __ | __ | __ | __ | __ | __ | __ | __ |

(12) | e1 | e2 | e3 | e4 | e5 | a1 | a2 | a3 | a4 | a5 | A6 | a7 | __ | __ | __ | __ | __ | __ | __ | __ |

with a capacity of 20.

容量为20。

Once you have created an ArrayList, you can ignore the capacity in all programming that follows; the logic is unaffected. However, the performance of the system under certain kinds of operations can be affected. Increasing the capacity, for instance, might well involved allocating a larger array, copying the first array into the second and then performing the operations. This can be quite slow compared to, e.g. the same operation on a linked list. Thus it is sensible to choose the capacity of an ArrayList to be bigger than, or at least comparable to, the actual number of elements expected in the real runtime environment.

一旦你创建了一个 ArrayList,你就可以在接下来的所有编程中忽略容量;逻辑不受影响。但是,系统在某些类型的操作下的性能会受到影响。例如,增加容量可能需要分配一个更大的数组,将第一个数组复制到第二个数组中,然后执行操作。与例如在链表上的相同操作相比,这可能相当慢。因此,选择 ArrayList 的容量大于或至少与实际运行时环境中预期的实际元素数量相当是明智的。

回答by khelwood

If you create a new array myArray = new Object[100]then you can read and write from myArray[0]to myArray[99](and you'll find it full of null).

如果您创建一个新数组,myArray = new Object[100]那么您可以从myArray[0]to读取和写入myArray[99](并且您会发现它充满了null)。

If you create an ArrayListmyList = new ArrayList(100)then you try and getor setany elements, you will get an IndexOutOfBoundsException, because the Listis empty until you addsomething to it.

如果你创建一个ArrayListmyList = new ArrayList(100)然后你尝试和getset任何元素,你会得到一个IndexOutOfBoundsException,因为在List你有add东西之前它是空的。

In summary, the array of size 100 will initially hold 100 nulls, but the Listwill be empty.

总之,大小为 100 的数组最初将容纳 100null秒,但List将是空的。

回答by Reid Harrison

This just seems poorly worded and potentially incorrect if I'm not understanding it correctly.

如果我没有正确理解它,这似乎措辞不佳并且可能不正确。

I believe what it is trying to say is that there is a difference between the initial capacity of the ArrayList and the initial size of the ArrayList.

我相信它想说的是 ArrayList 的初始容量和 ArrayList 的初始大小之间存在差异。

List<Employee> employees = new ArrayList<>(100);
int size = employes.size();

sizewill be 0 while the initial capacity is 100.

size将为 0,而初始容量为 100。

You are correct with how you are reading the source code.

您阅读源代码的方式是正确的。

回答by davidbak

The difference is between a fixed sizecontainer (data structure) and a variable sizecontainer.

区别在于固定大小的容器(数据结构)和可变大小的容器。

An arrayis a fixed sizecontainer, the number of elements it holds is established when the array is created and never changes. (When the array is created all of those elements will have some default value, e.g., null for reference types or 0 for ints, but they'll all be there in the array: you can index each and every one.)

一个阵列是一固定的大小的容器,它保存在创建阵列和从不改变当建立元件的数量。(创建数组时,所有这些元素都会有一些默认值,例如,引用类型为 null,整数为 0,但它们都将在数组中:您可以为每个元素建立索引。)

A listis a variable sizecontainer, the number of elements in it can change, ranging from 0 to as many as you want (subject to implementation limits). After creation the number of elements can either grow or shrink. At all times you can retrieve any element by its index.

列表是一个可变尺寸的容器中,在其元件的数目可以改变,范围从0到多达要(视情况而实现的限制)。创建后元素的数量可以增加或减少。在任何时候,您都可以通过索引检索任何元素。

But the Java concept Listis actually an interface and it can be implemented in many different ways. Thus, ArrayList, LinkedList, etc. There is a data structure "behind" the list to actually hold the elements. And that data structure itself might be fixed size or variable size, and at any given time might have the exact size of the number of elements in the list, or it might have some extra"buffer" space.

但是 Java 概念List实际上是一个接口,它可以通过多种不同的方式实现。因此,ArrayList,LinkedList等等。在列表“后面”有一个数据结构来实际保存元素。并且该数据结构本身可能是固定大小或可变大小,并且在任何给定时间可能具有列表中元素数量的确切大小,或者它可能有一些extra“缓冲区”空间。

The LinkedList, for example, always has in its underlying data structure exactly the same number of "places for elements" as are in the list it is representing. But the ArrayListuses a fixed length array as its backing store.

LinkedList,例如,总是在其底层的数据结构完全相同数量的“场所元件”为在它是代表列表。但是它ArrayList使用一个固定长度的数组作为它的后备存储。

For the ArrayList, at any given time the number of elements in the list might be different than the number of elements the array behind it can hold. Those "extra" places for elements just contain nulls or 0s or whatever, but the ArrayListnever gives you access to those places. As you add elements to the ArrayListthey take up more places in the underlying array, until finally the underlying array is full. The nextelement you add to the ArrayListcauses an entirely new fixed size array - somewhat bigger than the "current" array - to be allocated, and all the list elements copied to it (the original array is discarded). To prevent this expensive operation (allocation and copy) from happening too often the new array is larger than the current array (by some factor) and thus has elements which will not at that time hold elements of the list - they're empty (null or 0).

对于ArrayList,在任何给定时间,列表中的元素数可能与其后面的数组可以容纳的元素数不同。元素的那些“额外”位置仅包含空值或 0 或其他任何内容,但ArrayList永远不会让您访问这些位置。当您向ArrayList它们添加元素时,它们会在底层数组中占据更多位置,直到最终底层数组已满。在接下来您添加的元素ArrayList导致分配一个全新的固定大小数组 - 比“当前”数组大一些,并将所有列表元素复制到它(原始数组被丢弃)。为了防止这种昂贵的操作(分配和复制)过于频繁地发生,新数组大于当前数组(通过某种因素),因此具有当时不会保存列表元素的元素 - 它们是空的(空或 0)。

So, because there is (potentially) a difference between the number of elements in the list being represented, and the number of elements the implementing data structure can hold there are twoconcepts in force.

因此,由于被表示的列表中的元素数量(可能)与实现数据结构可以容纳的元素数量之间存在差异,因此有两个有效的概念。

The sizeof the list is the number of elements in it. The capacityof the list is the number of elements the backing data structure can hold at this time. The size will change as elements are added to or removed from the list. The capacity will change when the implementation of the list you're using needs it to. (The size, of course, will never be bigger than the capacity.)

列表的大小是其中元素的数量。的容量的列表是所述背衬的数据结构可以保持元件的数量在这个时候。大小将随着元素添加到列表或从列表中删除而改变。当您使用的列表的实现需要它时,容量会发生变化。 (当然,大小永远不会大于容量。)

(BTW, for fixed size containers the sizeis frequently called length, thus arrays have a property lengthand strings have a method length(). Different languages - sometimes even the same language - use "size" and "length" inconsistently, but they always mean size, and the term "capacity" is always used for the size/length of the underlying data structure.)

(顺便说一句,对于固定大小的容器,大小通常称为length,因此数组具有属性length并且字符串具有方法length()。不同的语言 - 有时甚至是相同的语言 - 不一致地使用“size”和“length”,但它们始终表示size,术语“容量”始终用于表示底层数据结构的大小/长度。)

回答by X09

Let's use a real life example. Consider an eighteen-seater bus, the capacity is eighteen passengers. The size of the passengers at any given time can be less than eighteen but not more than. When the number of passengers is eighteen, another passenger can't be accommodated.

让我们用一个现实生活中的例子。考虑一辆 18 座巴士,可容纳 18 名乘客。在任何给定时间,乘客的大小可以小于十八但不大于。当乘客人数为十八人时,不能再容纳另一名乘客。

In an ArrayList, the capacity has something in common with that of our bus in that it defines the number of elements that can fit in. Unlike our bus however, the capacity expands to accommodate the number of elements until Integer.MAX_VALUE.

在 ArrayList 中,容量与我们的总线的容量有一些共同点,因为它定义了可以容纳的元素数量。然而,与我们的总线不同的是,容量会扩展以容纳元素的数量,直到 Integer.MAX_VALUE。

The same goes for the size, just like our bus, the size of the elements in the list cannot exceed the capacity. Just imagine when 50 passengers are riding an eighteen-seater bus! You sure don't want to be in that bus.

大小也是一样,就像我们的总线一样,列表中元素的大小不能超过容量。试想一下,当 50 名乘客乘坐 18 座巴士时!你肯定不想在那辆公共汽车上。