简体   繁体   English

ArrayList与Array和List

[英]ArrayList vs Array and List

I've been programming for quite a bit and recently started learning more pure Computer Science topics (for a job interview). 我已经编程了很多,最近开始学习更多纯粹的计算机科学专题(面试)。

I know the difference between an Array and a LinkedList data structure, but now that I have started using Java I'm seeing this ArrayList, which I'm having trouble conceptualizing. 我知道Array和LinkedList数据结构之间的区别,但现在我已经开始使用Java了,我看到了这个ArrayList,我在构思时遇到了麻烦。

Web searches have only really shown me HOW to use them and WHEN to use them (benefits of each), but nothing can answer my question of: 网络搜索只是真正告诉我如何使用它们和何时使用它们(每个的好处),但没有什么能回答我的问题:

What is an ArrayList? 什么是ArrayList? My assumption is that it is a list that maintains memory references to each element, making it also able to act like an array. 我的假设是它是一个列表,它维护对每个元素的内存引用,使它也能像数组一样工作。

I also have a feeling since Java is open, that I should be able to look at the Class definition, but haven't figured out how to do that yet either. 我也有一种感觉,因为Java是开放的,我应该能够查看类定义,但还没有弄清楚如何做到这一点。

Thanks! 谢谢!

An ArrayList is a list that is directly backed by an array. ArrayList是由数组直接支持的列表。 More specifically, it's backed by an array that is dynamically resized. 更具体地说,它由一个动态调整大小的数组支持。 You can read a bit more about it in its source code ; 您可以在源代码中阅读更多相关内容; there are some pretty good comments to it. 有一些非常好的评论。

The reason that this is significant is due to how a LinkedList is implemented - as a traditional collection of nodes and references to other nodes. 这很重要的原因是由于LinkedList的实现方式 - 作为传统的节点集合和对其他节点的引用。 This has performance impacts in indexing and traversal, whereas with an ArrayList , since it's backed by an array, all one needs to do is index into the specific array to retrieve the value. 这对索引和遍历有性能影响,而对于ArrayList ,由于它由数组支持,所以需要做的就是索引特定数组以检索值。

I like to think of it as a data-structure that lets you enjoy both worlds, the quick-access to an index like with an array and the infinite growth of a list. 我喜欢把它想象成一个数据结构,让你享受这两个世界,快速访问像数组一样的索引和列表的无限增长。 Of course, there are always trade-offs. 当然,总是需要权衡利弊。

ArrayList is actually a wrapper to an array. ArrayList实际上是数组的包装器。 Every time the size of the array ends, a new array, twice the size, is created and all the data from the original array is copied to the new one. 每次数组的大小结束时,都会创建一个大小为两倍的新数组,并将原始数组中的所有数据复制到新数组中。

From the java doc: 来自java doc:

Resizable-array implementation of the List interface . List接口的可调整大小的数组实现 Implements all optional list operations, and permits all elements, including null. 实现所有可选列表操作,并允许所有元素,包括null。 In addition to implementing the List interface, this class provides methods to manipulate the size of the array that is used internally to store the list. 除了实现List接口之外,此类还提供了一些方法来操作内部用于存储列表的数组的大小。 (This class is roughly equivalent to Vector, except that it is unsynchronized.) The size, isEmpty, get, set, iterator, and listIterator operations run in constant time . (这个类大致相当于Vector,除了它是不同步的。) size,isEmpty,get,set,iterator和listIterator操作在恒定时间内运行 The add operation runs in amortized constant time, that is, adding n elements requires O(n) time . 添加操作以分摊的常量时间运行,即添加n个元素需要O(n)时间 All of the other operations run in linear time (roughly speaking). 所有其他操作都以线性时间运行(粗略地说)。 The constant factor is low compared to that for the LinkedList implementation. 与LinkedList实现相比,常数因子较低。

Each ArrayList instance has a capacity. 每个ArrayList实例都有一个容量。 The capacity is the size of the array used to store the elements in the list. 容量是用于存储列表中元素的数组的大小。 It is always at least as large as the list size. 它始终至少与列表大小一样大。 As elements are added to an ArrayList, its capacity grows automatically. 当元素添加到ArrayList时,其容量会自动增加。 The details of the growth policy are not specified beyond the fact that adding an element has constant amortized time cost. 除了添加元素具有恒定的摊销时间成本这一事实之外,未指定增长策略的详细信息。

An application can increase the capacity of an ArrayList instance before adding a large number of elements using the ensureCapacity operation. 在使用ensureCapacity操作添加大量元素之前,应用程序可以增加ArrayList实例的容量。 This may reduce the amount of incremental reallocation. 这可能会减少增量重新分配的数量。

This allows O(1) access for most of the operations like it would take with an array. 这允许对大多数操作进行O(1)访问,就像使用数组一样。 Once in a while you need to pay for this performance with an insert operation that takes much longer though. 偶尔,您需要使用插入操作来支付此性能,但需要更长时间。

This is called amortized complexity. 这称为摊销复杂性。 Each operation takes only O(1) aside for those times you need to double the size of the array. 对于那些需要将数组大小加倍的时间,每个操作只需要O(1) In those time you would pay O(n) but if you average it over n operations, the average time taken is only O(1) and not O(n) . 在那段时间你会支付O(n),但是如果你在n次操作中平均,那么平均花费的时间只有O(1)而不是O(n)

Let's take an example: 我们来举个例子:

We have an array of size 100 (n=100). 我们有一个100的数组(n = 100)。 You make 100 insert operations (to different indices) and each of them takes only O(1) , of course that all get-by-index operations also take O(1) (as this is an array). 你进行100次插入操作(到不同的索引),每个操作只需要O(1) ,当然所有的索引操作都需要O(1) (因为这是一个数组)。 On the 101 insertion, there's no more more capacity in the array so the ArrayList will create a new array, the size of 200, copy all the values to it ( O(n) operations) and then insert the 101st item. 在101插入时,数组中的容量不再增加,因此ArrayList将创建一个新数组,大小为200,将所有值复制到它( O(n)操作),然后插入第101项。 Until you fill out the array to 200 items, all of the operations would take O(1) . 在将数组填充到200个项目之前,所有操作都需要O(1)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM