繁体   English   中英

为什么在 LinkedList 末尾添加元素比 ArrayList 花费更长的时间?

[英]Why does adding an element at the end of LinkedList take longer than an ArrayList?

我了解到在 LinkedList 的末尾添加一个元素是 O(1),因为我们只是将 object 添加到列表的最后一个节点并且 ArrayList 也是 O(1),但最坏的情况是 O(n ) 因为当数组中没有空间时必须调整大小。 我试图对其进行测试,期待我学到的结果,但是 ArrayList 在添加 1000 万个元素方面比 LinkedList 快得多。

经过多次尝试,ArrayList 大约需要 570 毫秒,而 LinkedList 大约需要 1900 毫秒。

public static void listPractice(List<String> test) {
    long startTime = System.currentTimeMillis();
    for (int i = 0; i < 10_000_000; i++) {
        test.add(String.valueOf(i));
    }
    System.out.println(System.currentTimeMillis() - startTime);

}

看起来很奇怪。 我一直在阅读其他讨论,我看到很多程序员说 LinkedList,简而言之,有点糟糕。 这是证据,还是只是我缺少的东西?

向数组添加元素(不需要调整大小)需要将引用复制到空单元格中,并增加数组中 object 元素的计数。

将元素添加到链表需要分配一个新节点,将前最后一个条目的“下一个”链接指向新的最后一个条目,将新条目的“下一个”归零,将头部的“最后一个”链接指向新条目,并将新条目的上一个链接指向前一个最后一个条目。 然后将 object 引用复制到新节点中,并增加列表中元素的计数。

简而言之,链表比数组版本需要分配和多 4 次写入。

但是,如果您认为链表很糟糕,请尝试在您反复从包含 1000 万个条目的数组中删除最前面的元素的情况下使用数组。

有一些技术可以避免必须将所有条目打乱到数组中,但除非它是一个循环数组,否则它可能会打乱。 我见过的 ArrayList 来源会进行洗牌,因此删除 10,000,000 个条目中的第一个将使剩余的 9,999,999 个条目向下移动。 删除下一个条目将不得不向下移动剩余的 9,999,998 个条目......

更不用说您的 1000 万个条目数组需要能够获得连续的 40 或 80 兆字节的 memory。

教训是,不同的数据结构有不同的甜蜜点。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM