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

时间:2013-09-11 07:02:54

标签: java performance arraylist collections linked-list

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运行得更快。 有人可以解释哪个时间表现更好吗? 如果代码中有问题,请告诉我。谢谢!

4 个答案:

答案 0 :(得分:14)

如果您必须执行大量插入和不频繁查找,请使用LinkedList。如果执行的查找次数多于插入次数,请使用ArrayList

原因如下 - ArrayList由具有初始容量的数组支持。因此,如果您继续将项目插入列表中,则必须重新调整其数组容量以容纳新插入的项目,如果执行索引特定插入,它可能还必须移动现有项目。另一方面,LinkedList由链表支持,其中创建项总是在恒定时间内执行 - 创建项并将其分配到列表的末尾。这里没有重新调整。

现在要从ArrayList获取项目,它总是需要一段时间,因为它可以在一个恒定的时间内轻松索引后备数组。但是从LinkedList获取项目可能会导致您遍历整个链接列表以查找项目节点。因此,在这种情况下,它的执行率低于ArrayList

从上面的讨论中,您可以看到,当您需要执行更多插入操作时,LinkedList将始终优于ArrayList,因为后者具有与之关联的内部调整大小插入而前者不插入。另一方面,如果您不经常插入和频繁查找,ArrayList将始终优于LinkedList,因为对于后者,您可能必须遍历整个链表结构才能找到所需的项目,而前者将能够在不断的时间内快速找到具有数组索引的项目。

当您处理大量物品(例如,数千件物品)时,所有上述效果都会显现并影响您的应用程序的性能。对于较少的项目,性能差异不太明显。

现在,关于你的代码,你有一些严重的问题。对于初学者,你使用的是原始类型,这很糟糕,因为你失去了泛型所提供的所有类型安全性。编写新代码时,应始终使用Collection 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);
}

请参阅 Effective Java 第23项:不要在新代码中使用原始类型以获取详细说明。

修改

根据评论中的讨论,您应该明白,如果您需要在列表中间或随机位置插入元素,那么ArrayListLinkedList方面优于memcpy性能,因为前者将使用ArrayList来移动非常快的元素,而后者将必须遍历到所需的索引以正确插入新元素,这更慢。因此,对于随机插入LinkedList也优于LinkedList。唯一的情况ArrayList优于{{1}},如果您只在列表的末尾插入,并且有很多这些插入。

答案 1 :(得分:2)

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

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

答案 2 :(得分:1)

ArrayList由数组支持,LinkedList支持的Node与refernece链接。

因此,对ArrayList的操作是对数组的实际评估操作。添加操作以分摊的常量时间运行,即添加n个元素需要O(n)时间。所有其他操作都以线性时间运行(粗略地说)。与LinkedList实现相比,常数因子较低。

并且在LinkedList上,所有操作都按照预期的方式执行双向链接列表。索引到列表中的操作将从开头或结尾遍历列表,以较接近指定索引为准。

详细了解文档 -

答案 3 :(得分:0)

LinkedList将在添加每个元素时创建新节点,而不在数组列表中。

如果您知道初始大小,则在创建时将其传递给ArrayList,它可以避免重建数组 像new ArrayList(100);