如何选择正确的List实现?

cf *_*ica 7 java performance list

这个CodeReview答案,

您似乎将ArrayList用于所有目的.Java中还有其他List类型比ArrayList更适合某些情况.您应该看看这些并尝试了解何时使用哪个列表.在这种特殊情况下,链接列表更好.

我也倾向于使用ArrayList相当多,并且没有看到选择其他列表类型背后的逻辑.

List文档显示五个主要List子类:ArrayList,CopyOnWriteArrayList,LinkedList,Stack,和Vector.

ArrayList文档中,

size,isEmpty,get,set,iterator和listIterator操作以恒定时间运行.添加操作以分摊的常量时间运行,即添加n个元素需要O(n)时间.所有其他操作都以线性时间运行(粗略地说).与LinkedList实现相比,常数因子较低.

这表明ArrayList通常表现优异LinkedList(这个支持率很高的问题支持这个断言),尽管LinkedList文档并没有对性能有所了解:

对于双向链表,所有操作都可以预期.

CopyOnWriteArrayList 对于不变的列表似乎只有用,因为每次修改的完整快照对于正常使用来说似乎都是非常昂贵的.

即使是Stack文档也不建议使用它:

Deque接口及其实现提供了更完整和一致的LIFO堆栈操作集,应优先使用此类.

由于Vector是同步的,而其余的List子类不同步,在我看来,这Vector将是线程安全环境中的最佳选择.

然而,即使在阅读了文档之后,我仍然认为我不明白TwoThe的答案来自哪里.CopyOnWriteArrayList并且Vector每个似乎都有一个专门的用例,Stack似乎不值得使用,并且ArrayList似乎优于LinkedList.

我在这里错过了什么,在什么情况下另一个List实施优于ArrayList什么?

Gen*_*ene 0

我同意这ArrayList对于许多用途来说都是正确的选择。LinkedList正如您所说,每个元素使用 8 或 16 字节的内存作为指针,索引是 O(length) 。

那有什么LinkedLists优点呢?

  • 迭代期间的删除remove()是常数时间。ArrayList其长度为O(长度)。
  • 添加新的列表节点始终需要相同的时间。当ArrayList空间不足时,会在后台分配更大的内存块,并复制所有内容。虽然每个元素在许多操作中的摊销时间是恒定的,但单个元素的成本add()是 O(length)。如果这种周期性延迟不可接受,则不能使用ArrayList.

至于其他的,Vector可以追溯到 Java 的早期。它是线程安全的。因为这会增加每个操作的成本,所以或多或少不推荐使用它,而倾向于使用ArrayList. 当您需要线程安全时,可以SynchronizedList使用ArrayList. 同样,Stack或多或少已被弃用,取而代之的是更现代且非线程安全的Deque

CopyOnWriteArrayList是一个线程安全的数据列表,它通过某种不寻常的措施来获得其安全性,即在任何元素发生更改时复制完整数组。虽然这听起来很疯狂,但如果有许多线程迭代同一个数组,这是有意义的,因为更改不必等待迭代全部完成,而其他并发列表通常是这种情况。