在这里回答的每一个人都是正确的。他们的想法都是正确的,这在很大程度上取决于您的使用模式,即没有一刀切的列表。但是在我写这篇文章的时候,他们都忘了提到(或者我是草率的读者)LinkedList 处于最佳状态时的一个用例:迭代器定位插入。这意味着,如果你不只是
LinkedList::add(int index, E element)
Inserts the specified element at the specified position in this list.
这似乎是他们用来获取统计数据的方法,但是
iterator.insert(E element)
iterator
通过任一获得
public abstract ListIterator<E> listIterator(int index)
Returns a list-iterator of the elements in this list (in proper sequence), starting at the specified position in the list.
或者
public Iterator<E> iterator()
Returns an iterator over the elements in this list (in proper sequence).
,那么您一定会获得有史以来最好的任意插入性能。当然,这意味着您可以限制对 iterator() 和 listIterator() 的调用次数,以及迭代器在列表中的移动次数(例如,您只能对列表进行一次顺序传递来执行所有需要的插入操作)。这使得它的用例数量非常有限,但它们仍然是经常出现的用例。LinkedList 在它们中的表现是它被(并且将在未来)保存在所有语言的所有容器集合中的原因,而不仅仅是 Java。
PS。当然,以上所有内容都适用于所有其他操作,例如 get()、remove() 等。即通过迭代器精心设计的访问将使所有这些操作都成为 O(1),实际常数非常小。当然,对于所有其他列表也可以这样说,即迭代器访问将加快它们的速度(但速度很慢)。但不是 ArrayList 的 insert() 和 remove() - 它们仍将是 O(n)... 而不是 TreeList 的 insert() 和 remove() - 树平衡开销不是您可以避免的... 而 TreeList可能有更多的内存开销......你明白我的想法。总而言之,LinkedList 是针对列表的小型高性能扫描类操作。这是否是您需要的用例 - 只有您自己才能判断。
PSS。也就是说,我因此也留下了
很想得出结论,他们已经摊销或忽略了 ArrayList 的成长之痛,并且没有考虑到 LinkedList 中已经定位的项目的插入和删除时间。