添加元素时java链表比arraylist慢?

时间:2011-03-17 22:26:56

标签: java optimization arraylist linked-list

我认为链接列表在添加元素时应该比arraylist更快?我刚刚测试了添加,排序和搜索元素所需的时间(arraylist vs linkedlist vs hashset)。我只是使用java.util类进行arraylist和linkedlist ...使用每个类可用的add(object)方法。

arraylist out在填写列表时执行了链表...并且在列表的线性搜索中。

这是对的吗?我在实施中做错了吗?

** * ** * ** * 的** * *** 修改 * ** * ** * ** * ** * ** * *

我只是想确保我正确使用这些东西。这就是我正在做的事情:

public class LinkedListTest {

    private List<String> Names;

    public LinkedListTest(){
            Names = new LinkedList<String>();
    }

然后我只使用链表列表方法,即“Names.add(strings)”。当我测试arraylists时,它几乎相同:

public class ArrayListTest {

    private List<String> Names;

    public ArrayListTest(){
            Names = new ArrayList<String>();
    }

我做得对吗?

6 个答案:

答案 0 :(得分:11)

是的,没错。 LinkedList必须在每次插入时进行内存分配,而ArrayList允许执行更少的内存分配,并为其amortized O(1) insertion。内存分配看起来很便宜,但实际上可能非常昂贵。

由于引用的位置,LinkedList的线性搜索时间可能较慢:ArrayList元素更靠近,因此cache misses更少。

当您计划仅在List的末尾插入时,ArrayList是实施选择。

答案 1 :(得分:3)

请记住:

  • 对于给定数量的元素,“原始”表现有所不同,以及不同结构比例;
  • 不同的结构在不同的操作中表现不同,这基本上是您在选择使用哪种结构时需要考虑的部分。

因此,例如,链接列表在添加到结尾时还有更多工作要做,因为它有一个额外的对象来分配和初始化每个项目添加,但无论每个项目的“内在”成本如何,两个结构都将具有O (1)添加到列表末尾的性能,即无论列表的大小如何,每次添加都有一个有效的“常量”时间,但是ArrayList与LinkedList之间的常量会有所不同,后者可能会更大。 / p>

另一方面,链表有恒定的时间添加到列表的开头,而在ArrayList的情况下,元素必须“shuftied”,这个操作花费一些时间与数字成比例元素。但是,对于给定的列表大小,比如100个元素,“shufty”100个元素可能比分配和初始化链表的单个占位符对象更快(但是当你到达时,比如,一千或一百万个物体或任何阈值,它不会是。)

因此,在您的测试中,您可能想要考虑给定大小的操作的“原始”时间以及这些操作扩展随着列表大小的增长。

答案 2 :(得分:1)

当将一个元素添加到LinkedList的后面时(在Java LinkedList中实际上是一个双向链表),它是一个O(1)操作,就像在它前面添加一个元素一样。在i位置添加元素大致是O(i)操作。

因此,如果您要添加到列表的前面,则LinkedList会明显更快。

答案 3 :(得分:1)

为什么你认为LinkedList会更快?在一般情况下,插入数组列表只是更新单个数组单元的指针(使用O(1)随机访问)的情况。 LinkedList插入也是随机访问,但必须分配一个“单元”对象来保存条目,并更新一对指针,以及最终设置对正在插入的对象的引用。

当然,可能需要定期调整ArrayList的后备阵列(如果选择初始容量足够大,则不会出现这种情况),但由于阵列呈指数级增长,因此摊销成本会很低,并且受O(lg n)复杂性限制。

简单地说 - 插入数组列表要简单得多,因此总体来说要快得多。

答案 4 :(得分:1)

在这些情况下,链接列表可能比数组列表慢,原因有几个。如果要插入列表的末尾,则阵列列表可能已经分配了此空间。底层数组通常以大块的形式增加,因为这是一个非常耗时的过程。因此,在大多数情况下,在后面添加元素只需要粘贴在引用中,而链表需要创建节点。在前面和中间添加应该为两种类型的列表提供不同的性能。

列表的线性遍历在基于数组的列表中总是更快,因为它必须只能正常遍历数组。这需要每个单元一次解除引用操作。在链表中,列表中的节点也必须被解除引用,占用的时间加倍。

答案 5 :(得分:0)

ArrayList访问随机索引数据的速度更快,但在列表中间插入元素时速度较慢,因为使用链表只需更改参考值。但是在数组列表中,你必须在插入的索引之后复制所有元素,后面有一个索引。

编辑:是不是有一个链表实现,它记住了最后一个元素?这样做会加快使用链表的插入速度。