我一直是一个简单使用的人:

List<String> names = new ArrayList<>();

我使用接口作为可移植性的类型名称,这样当我问类似这样的问题时,我就可以修改代码。

LinkedList何时应用于ArrayList,反之亦然?


当前回答

ArrayList是您想要的。LinkedList几乎总是一个(性能)bug。

为什么LinkedList很糟糕:

它使用了大量小内存对象,因此影响了整个过程的性能。许多小对象不利于缓存位置。任何索引操作都需要遍历,即具有O(n)性能。这在源代码中并不明显,导致算法O(n)比使用ArrayList时慢。获得好的表现是很棘手的。即使big-O性能与ArrayList相同,它也可能会明显变慢。在源代码中看到LinkedList很刺耳,因为它可能是错误的选择。

其他回答

ArrayList和LinkedList都实现了List接口,它们的方法和结果几乎相同。然而,它们之间几乎没有区别,这取决于需求,使一个优于另一个。

阵列列表与链接列表

1) 搜索:与LinkedList搜索操作相比,ArrayList搜索操作非常快。ArrayList中的get(int index)给出了O(1)的性能,而LinkedList的性能为O(n)。

原因:ArrayList为其元素维护基于索引的系统,因为它隐式使用数组数据结构,这使得在列表中搜索元素的速度更快。另一方面,LinkedList实现了双链接列表,这需要遍历所有元素来搜索元素。

2) 删除:LinkedList删除操作提供O(1)性能,而ArrayList提供可变性能:最坏情况下(删除第一个元素时)为O(n),最好情况下(移除最后一个元素时,为O(2)。

结论:LinkedList元素删除速度比阵列列表。

原因:LinkedList的每个元素都有两个指针(地址),指向列表中的两个相邻元素。因此,移除仅需要改变将要移除的节点的两个相邻节点(元素)中的指针位置。当在ArrayList中时,需要移动所有元素以填充移除的元素所创建的空间。

3) 插入性能:LinkedList add方法提供O(1)性能,而ArrayList在最坏情况下提供O(n)性能。原因与删除说明相同。

4) 内存开销:ArrayList维护索引和元素数据,而LinkedList维护相邻节点的元素数据和两个指针

因此LinkedList中的内存消耗相对较高。

这些类之间几乎没有相似之处,如下所示:

ArrayList和LinkedList都是List接口的实现。它们都保持元素插入顺序,这意味着在显示ArrayList和LinkedList元素时,结果集将具有元素插入列表的相同顺序。这两个类都是非同步的,可以使用Collections.synchronizedList方法显式同步。这些类返回的迭代器和listIterator是快速失败的(如果在创建迭代器之后的任何时候对列表进行结构修改,除了通过迭代器自己的remove或add方法之外,其他任何方式,迭代器都会抛出ConcurrentModificationException)。

何时使用LinkedList,何时使用ArrayList?

如上所述,与ArrayList(O(n))相比,插入和删除操作在LinkedList中提供了良好的性能(O(1))。因此,若应用程序中需要频繁添加和删除,则LinkedList是最佳选择。搜索(get方法)操作在Arraylist(O(1))中很快,但在LinkedList(O(n))中不快因此,如果添加和删除操作更少,搜索操作需求更多,ArrayList将是您的最佳选择。

除了上面的其他好参数之外,您应该注意到ArrayList实现了RandomAccess接口,而LinkedList实现了Queue。

因此,他们解决的问题略有不同,效率和行为有所不同(见他们的方法列表)。

我的经验法则是,如果我需要一个集合(即不需要是一个列表),那么如果你事先知道大小,或者可以自信地知道大小,或知道它不会有太大变化,那么就使用ArrayList。如果您需要随机访问(即使用get(index)),请避免LinkedList。基本上,只有当您不需要索引访问并且不知道正在分配的集合的(近似)大小时,才使用LinkedList。此外,如果您要进行大量添加和删除(再次通过Collection接口),则LinkedList可能更可取。

链接列表的一个重要特性(我在另一个答案中没有看到)是两个列表的串联。对于数组,这是O(n)(+某些重新分配的开销),对于链接列表,这只是O(1)或O(2);-)

重要提示:对于Java的LinkedList,这不是真的!请参阅Java中是否有一种快速的链表连接方法?

1) 基础数据结构

ArrayList和LinkedList之间的第一个区别在于,ArrayList由Array支持,而LinkedList由LinkedList支持。这将导致性能的进一步差异。

2) LinkedList实现Deque

ArrayList和LinkedList之间的另一个区别是,除了List接口之外,LinkedList还实现了Deque接口,该接口为add()和poll()以及其他几个Deque函数提供先进先出操作。3) 在ArrayList中添加元素如果不触发Array的重新调整大小,则在ArrayList中添加元素是O(1)操作,在这种情况下,它变为O(log(n))。另一方面,在LinkedList中添加一个元素则是O(2)操作,因为它不需要任何导航。

4) 从位置移除元素

为了从特定索引中删除元素,例如通过调用remove(index),ArrayList执行复制操作,使其接近O(n),而LinkedList需要遍历到该点,这也使其成为O(n/2),因为它可以根据接近度从任意方向遍历。

5) 遍历ArrayList或LinkedList

迭代是LinkedList和ArrayList的O(n)操作,其中n是元素的数量。

6) 从位置检索元素

get(index)操作在ArrayList中为O(1),而在LinkedList中为其O(n/2),因为它需要遍历该条目。虽然,在大O符号中,O(n/2)只是O(n),因为我们忽略了那里的常数。

7) 内存

LinkedList使用一个包装对象Entry,这是一个静态嵌套类,用于存储数据和下一个和上一个节点,而ArrayList只在Array中存储数据。

因此,除了Array在将内容从一个Array复制到另一个Array时执行重新调整大小操作的情况外,ArrayList的内存需求似乎比LinkedList少。

如果Array足够大,那么此时可能会占用大量内存并触发垃圾收集,这会降低响应时间。

从ArrayList与LinkedList之间的所有差异来看,ArrayList在几乎所有情况下都是比LinkedList更好的选择,除非您经常执行add()操作而不是remove()或get()操作。

修改链接列表比修改ArrayList更容易,尤其是当您从开始或结束处添加或删除元素时,因为链接列表内部保留了这些位置的引用,并且可以在O(1)时间内访问。

换句话说,您不需要遍历链接列表就可以到达要添加元素的位置,在这种情况下,添加就变成了O(n)操作。例如,在链接列表中间插入或删除元素。

在我看来,在Java中,使用ArrayList而不是LinkedList来实现大多数实际用途。