Java 要使用列表的哪个实现?

Java 要使用列表的哪个实现?,java,performance,memory-management,collections,Java,Performance,Memory Management,Collections,在我的程序中,我经常使用集合来存储对象列表。目前我使用ArrayList来存储对象。 我的问题是:这是最好的选择吗?使用LinkedList是否更好?还是别的什么 考虑的标准是: 内存使用 演出 我需要的行动包括: 向集合添加元素 遍历元素 有什么想法吗 更新:基于此讨论以及以下讨论,我的选择是:ArrayList:): 链表可以更快地添加/删除内部元素(即不是头或尾) Arraylist的迭代速度更快这是插入优化和检索优化之间的经典折衷。正如您所描述的,任务的常见选择是Array

在我的程序中,我经常使用集合来存储对象列表。目前我使用ArrayList来存储对象。 我的问题是:这是最好的选择吗?使用LinkedList是否更好?还是别的什么

考虑的标准是:

  • 内存使用
  • 演出
我需要的行动包括:

  • 向集合添加元素
  • 遍历元素
有什么想法吗

更新:基于此讨论以及以下讨论,我的选择是:ArrayList:):


链表可以更快地添加/删除内部元素(即不是头或尾)


Arraylist的迭代速度更快

这是插入优化和检索优化之间的经典折衷。正如您所描述的,任务的常见选择是ArrayList。

ArrayList
适合您(以及大多数其他)的目的。它具有非常小的内存开销,并且对于大多数操作具有良好的摊销性能。不理想的情况相对较少:

  • 名单非常大
  • 您经常需要执行以下操作之一:
    • 在迭代期间添加/删除项
    • 从列表的开头删除项目

如果只在列表末尾添加,
ArrayList
应该可以。从
ArrayList
的文档中:

除了添加要素具有固定摊余时间成本这一事实外,未详细说明增长政策


而且
ArrayList
也应该比链表使用更少的内存,因为您不需要为链接使用空间。

我总是默认使用ArrayList,并且在您的情况下也会使用,除非

  • 我需要线程安全(在这种情况下,我开始研究java.util.concurrent中的列表实现)
  • 我知道我将要对列表进行大量的插入和操作,或者分析表明我使用ArrayList是一个问题(非常罕见)

至于在第二种情况下选择什么,这个SO.com线程有一些有用的见解:

这取决于您的使用情况

您是否将添加到列表的末尾?这两个都可以。 您是否将添加到列表的开头?LinkedList更适合这样做。 您是否需要随机访问(您是否会调用
get(n)
?ArrayList更适合这样做

两者都擅长迭代,对于
next()
,这两种迭代器实现都是O(1)


如果有疑问,请使用每个实现测试您自己的应用程序,并做出您自己的选择。

我知道我迟到了,但是,也许可以帮助您,不仅是现在,而且是将来……

根据您的标准,您应该使用LinkedList

LinkedList实现了Deque接口,这意味着它可以在固定时间(1)内添加到列表的开始或结束。此外,ArrayList和LinkedList都将在(N)时间内迭代

您不应该仅仅因为列表已满时添加元素的成本而使用ArrayList。在这种情况下,添加元素将是(N),因为正在创建新数组并将所有元素从一个数组复制到另一个数组


此外,ArrayList将占用更多内存,因为备份阵列的大小可能没有完全填满。

可能重复。请详细说明“生产力”您是否主要将其添加到列表的末尾或任意位置?嗯。迭代时可能会更快,尽管我不认为这会超过边际。真正的好处应该是以随机顺序访问元素……据我所知,两者都有O(n)迭代。O(n)迭代超过n个元素。若你们读到这里并在那个里改变方式,链表迭代器将不会抛出……详细说明这一点:若ArrayList的迭代器在迭代时检测到改变,它将抛出一个异常。另外,从一开始就删除a-la队列更好地通过链表完成,原因很明显。@GregC:LinkedList的迭代器在同时进行修改时不会引发异常?如果是的话,为什么这么好?看来我错了。。。我得试试。。。。引述:“该类的迭代器和listIterator方法返回的迭代器是快速失效的:如果在创建迭代器后的任何时间,以迭代器自己的remove或add方法以外的任何方式对列表进行结构修改,迭代器将抛出ConcurrentModificationException。因此,在面对并发修改时,迭代器会快速、干净地失败,而不是在将来的不确定时间冒着任意、不确定行为的风险。“我的想法是……如果有人在修改列表,并且他们没有在被迭代的元素的左侧或右侧更改任何内容,那么就没有问题了。@GregC:乍一看,这听起来合乎逻辑,但竞争条件并没有那么简单。不过,你误解了我的观点:迭代器(和ListIterator)接口本身具有添加/删除方法,可以在迭代过程中安全地使用这些方法来修改列表(对于LinkedList来说,这样做非常有效)迭代整个集合的速度很快,而且由于链接列表中的链接必须存储在某个地方,所以内存占用也较少。感谢您提供了一个非常有趣的讨论的链接!@Thilo-我从来没有说过。我说过除非我需要线程安全,否则我默认使用ArrayList。为了清楚起见,我将修改我的答案,说我去java.util.concurrent中的列表实现。我的同事刚刚编写了一个简单的测试-将元素添加到不同位置不同大小的列表中。结果如下:我自己做了一个简单的测试。结果如下:-简单添加(List.add(“a”)):ArrayList在大小范围从1到100000上比LinkedList快3-5倍。添加到列表头(list.add(0,“A”):大小为1时,时间相等;大小为100时,LinkedList快2倍;大小为1000时,LinkedList