哪一个运行得更快,ArrayList还是LinkedList?

List li = new LinkedList();

for (int i = 0; i < 100; i++) {
    li.add(i);
}

long start1 = System.nanoTime();
li.get(57);

long end1 = System.nanoTime();
long diff1 = end1-start1;

System.out.println("Time taken by LinkedList = "+diff1);

List al = new ArrayList();
for (int i = 0; i < 100; i++) {
    al.add(i);
}

无论我对这两个列表执行什么操作,当我打印出所花费的时间时,ArrayList总是比LinkedList运行得更快。有人能解释一下在所花费的时间方面哪个表现更好吗?如果代码中有问题,也请告诉我。谢谢!


答案 1

如果必须执行大量插入操作且查找频率不高,请使用 .如果执行的查找次数多于插入项,请使用此选项。LinkedListArrayList

原因如下 - 由具有初始容量的阵列支持。因此,如果继续将项目插入到列表中,则有时它必须重新调整其数组容量以容纳新插入的项目,并且如果执行索引填充插入,则可能还必须移动现有项目。另一方面,由链接列表支持,其中创建项目始终在常量时间内执行 - 创建一个项目并将其分配给列表的末尾。此处不会发生重新调整。ArrayListLinkedList

现在要从 中获取一个项目,它总是需要恒定的时间量,因为它可以很容易地在恒定时间内索引支持数组。但是,从 中获取项目可能会导致您遍历整个链接列表以查找项目节点。因此,它的性能低于本例。ArrayListLinkedListArrayList

从上面的讨论中可以看出,当您有更多的插入要做时,总会表现出色,因为后者具有与插入相关的内部调整大小成本,而前者则没有。另一方面,如果您不频繁插入和频繁查找,则性能将始终优于后者,因为对于后者,您可能必须遍历整个链接列表结构才能找到所需的项目,而前者将能够以恒定时间使用数组索引快速找到您的项目。LinkedListArrayListArrayListLinkedList

上述所有效果都将可见,并在处理大量项目(例如,数千个项目)时影响应用程序的性能。对于较少的项目,性能差异不是很明显。

现在,关于你的代码,你有一些严重的问题。首先,您使用的是原始类型,这很糟糕,因为您失去了泛型必须提供的所有类型安全性。编写新代码时,应始终使用集合 API 的通用版本。因此,请按如下方式更改代码 -

List<Integer> li = new LinkedList<Integer>();
for (int i = 0; i < 100; i++) {
    li.add(i);
}

long start1 = System.nanoTime();
li.get(57);

long end1 = System.nanoTime();
long diff1 = end1 - start1;

System.out.println("Time taken by LinkedList = "+diff1);

List<Integer> al = new ArrayList<Integer>();
for (int i = 0; i < 100; i++) {
    al.add(i);
}

有关详细说明,请参阅有效的 Java第 23 项:不要在新代码中使用原始类型

编辑

从评论中的讨论中,您应该可以明显看出,如果您需要在列表中间或随机位置插入元素,那么在性能方面表现优异,因为前者将用于移动非常快的元素,而后者将不得不遍历到所需的索引才能正确插入新元素, 这比较慢。因此,对于随机插入也表现出色。唯一优于此种情况的是,如果您只在列表末尾插入,并且有很多这样的插入。ArrayListLinkedListmemcpyArrayListLinkedListLinkedListArrayList


答案 2

数组列表在读取方面将始终比链接列表快。ArrayList基本上是数组实现,为数组分配的内存是按顺序分配的,因此读取速度更快。但是,当您使用需要在列表之间插入或删除的列表时,则链接列表更快。因为它只需要在节点之间添加链接。在这两种情况下,数组列表会变慢。用法可以是:

ArrayList - 更快的读取操作,列表之间的插入,删除速度较慢。链表 - 与数组列表相比,读取操作速度慢,但在列表之间插入,删除速度更快。


推荐