【问题标题】:Java, Adding time LinkedList vs ArrayListJava,添加时间 LinkedList vs ArrayList
【发布时间】:2019-10-09 19:28:14
【问题描述】:

只是将整数添加到 Arraylist 和 Linkedlist 到最后一个位置,为什么添加 arrayList 比添加 linkedlist 更快?我编译了很多很多次,在arraylist中添加更快,为什么?

据我所知,ArrayList 将数组复制 2^n+1 大小。而linkedlist只改变节点

class Test1 {

public static void main(String[] args) {
    ArrayList<Integer> arrayList = new ArrayList<>();
    LinkedList<Integer> linkedList = new LinkedList<>();

    addToList(arrayList);
    System.out.println("-----------------");
    addToList(linkedList);

}

public static void addToList(List list) {
    long start = System.currentTimeMillis();
    for (int i = 0; i < 5_000_000; i++) {
        list.add(i);
    }
    long end = System.currentTimeMillis();
    System.out.println(end - start);

}

}

【问题讨论】:

标签: java data-structures


【解决方案1】:

当您添加到ArrayList 时,您只需要将整数存储在后备数组中。每隔一段时间,当后备数组填满时,您必须分配一个新数组并将所有旧项目复制到新数组中。给定 500 万个整数,您将不得不进行大约 20 次分配和复制(取决于列表的初始大小)。

要添加到链表,每次添加都需要您:

  1. 为新的链表节点分配内存并初始化。
  2. 将新节点链接到列表末尾。

ArrayListLinkedList 的所有额外工作都是通过 add 方法在幕后完成的。

500 万个链表节点分配和链接的开销高于 500 万个 ArrayList 插入的开销,即使你算上 ArrayList 必须执行的 20 次左右的分配和复制操作。它填满了。

所以,虽然每个操作都需要固定时间(尽管在ArrayList 的情况下它确实是摊销 固定时间),但附加到链表的常数要高于附加到链表的常数ArrayList.

【讨论】:

    【解决方案2】:

    ArrayList 不会每次都复制整个数组,它会在当前数组中没有更多空间时创建一个大小翻倍的新数组。

    所以如果你有一个ArrayList 有 3 个元素,那么底层数组的大小可能是 4。因此,添加一个新元素不需要创建一个新数组并复制这 3 个值,因此时间复杂度为O(1)。

    它们现在都是 O(1),但是 ArrayList 只需要将值放在内存中的正确位置,而 LinkedList 需要分配新空间(为新节点)。

    【讨论】:

    • 3 个元素的数组列表大小是 3,而不是 4
    猜你喜欢
    • 1970-01-01
    • 2014-09-17
    • 2011-01-25
    • 2017-10-20
    • 2021-12-19
    • 2023-04-03
    • 2015-04-09
    • 1970-01-01
    • 2012-10-10
    相关资源
    最近更新 更多