我一直在编程,最近开始学习更纯粹的计算机科学知识(为了面试)。我知道数组和链表数据结构之间的区别,但现在我开始使用Java时看到了这个ArrayList,我很难理解它。
网络搜索只是向我展示如何使用它们和何时使用它们(每个的好处),但没有回答我的问题:
什么是ArrayList? 我的假设是它是一个列表,维护着每个元素的内存引用,使其也能像数组一样运行。
我还有一种感觉,既然Java是开放的,我应该能够查看类定义,但我还没弄清楚如何做到这一点。
谢谢!
我一直在编程,最近开始学习更纯粹的计算机科学知识(为了面试)。我知道数组和链表数据结构之间的区别,但现在我开始使用Java时看到了这个ArrayList,我很难理解它。
网络搜索只是向我展示如何使用它们和何时使用它们(每个的好处),但没有回答我的问题:
什么是ArrayList? 我的假设是它是一个列表,维护着每个元素的内存引用,使其也能像数组一样运行。
我还有一种感觉,既然Java是开放的,我应该能够查看类定义,但我还没弄清楚如何做到这一点。
谢谢!
ArrayList
是一个由数组直接支持的列表。更具体地说,它是由可动态调整大小的数组支持的。您可以在源代码中了解更多信息; 有一些相当不错的注释。LinkedList
的实现方式 - 作为节点和其他节点的引用的传统集合。这对索引和遍历产生性能影响,而对于ArrayList
,由于它是由数组支持的,所有需要做的就是索引到特定的数组中以检索值。ArrayList
实际上是一个数组的包装器。每当数组大小到达末尾时,都会创建一个新的大小为原来两倍的数组,并将原始数组中的所有数据复制到新数组中。每个ArrayList实例都有一个容量。容量是用于存储列表中元素的数组的大小。它始终至少与列表大小一样大。当元素添加到ArrayList时,其容量会自动增长。增长策略的详细信息未指定,除了添加元素具有固定的摊销时间成本之外。
应用程序可以使用ensureCapacity操作在添加大量元素之前增加ArrayList实例的容量。这可能会减少增量重新分配的数量。
这使得大多数操作像使用数组一样具有O(1)的访问速度。但是,偶尔需要通过插入操作来支付这种性能,这需要花费更长的时间。这被称为摊销复杂度。每个操作只需要O(1),除了那些需要将数组大小加倍的时候。在这些时候,您需要支付O(n),但如果您平均n次操作,平均所需的时间只有O(1)而不是O(n)。
让我们举个例子:
我们有一个大小为100(n=100)的数组。您进行了100次插入操作(到不同的索引),每个操作仅需要 O(1),当然,所有通过索引获取元素的操作也需要 O(1)(因为这是一个数组)。在第101次插入时,数组已经没有更多的容量,所以ArrayList将创建一个新的大小为200的数组,将所有值复制到其中(O(n) 操作),然后再插入第101个项目。直到填满数组为止,所有操作都需要 O(1)。
ArrayList
源代码(例如在IntelliJ中,选中代码中的ArrayList
,然后按CTRL + 左键单击)。你会发现ArrayList
本质上是一个包装过的Object[]
,并且还有很多方便的插入、删除等方法。 - Paul Boddington