【问题标题】:Why is removing an element from the start of an ArrayList slower than that from its end?为什么从 ArrayList 开头删除元素比从结尾删除元素慢?
【发布时间】:2016-04-30 17:40:30
【问题描述】:

有人告诉我

当我们创建一个 ArrayList 时,内部是一个特定大小的 Array (比如 50)被创建。当添加到列表中的项目超过 50,在内部创建一个更大的新数组(比如 100),并且 他们将原始数组的项目复制到这个新数组中。

然后有人告诉我

当我们从列表末尾删除一个项目时,所有这一切都完成了 内部是在内部减少列表的大小。但是 删除位于开头某处的元素 ArrayList 非常慢,因为它必须复制所有 后续项目退一步,所以很慢。

但是正如第一个引用中所暗示的那样,ArrayList 在内部由 Array 表示,并且由于一旦分配了数组就无法更改数组的大小;您必须创建一个新数组。

  • 这意味着当一个元素在 ArrayList 的末尾被移除时,一个新的数组是 内部创建,其大小比原始大小小1 数组,并将第一个数组的所有元素复制到新数组中。
  • 当从 ArrayList 的开头删除一个元素时,一个新的 数组是在内部创建的,其大小比 原始数组,并将第一个数组的所有元素复制到 新的,这样每个 subsequent 元素在新的索引位置 数组比该元素在 上一个/原始数组。

我的概念正确吗?

如果是,那么我不明白为什么从数组列表的开头删除元素所需的时间/步数比从末尾删除元素时要慢得多数组。

请帮助我理解。

【问题讨论】:

    标签: java arrays arraylist


    【解决方案1】:

    不,这是不正确的。仅当数组中没有足够空间容纳所有元素时才会创建新数组。

    一个包含 4 个元素(a、b、c、d)的 ArrayList 表示如下:

    array: [a, b, c, d, null, null, null, null, null, null]
    size: 4
    

    从列表中删除最后一个元素会将其内容更改为

    array: [a, b, c, null, null, null, null, null, null, null]
    size: 3
    

    列表所要做的就是将大小整数递减,并将第 4 个元素设置为 null。

    删除第一个元素会将其内容更改为

    array: [b, c, null, null, null, null, null, null, null, null]
    size: 2
    

    列表必须减小大小,将a复制到第一个索引,将b复制到第二个索引,将第三个索引设置为null。这需要更多的工作,尤其是在列表更长的情况下。

    【讨论】:

    • 谢谢。在第二个伪代码/whatever-it-is-call 中,3 是 ArrayList 的大小,但在内部表示 ArrayList 的 Array 的大小仍然是 4,对吧?
    • 没有。如您所见,数组长度为 10。最后 6 个元素为空(在第一个 sn-p 中)。长度保持为 10,直到第 11 个元素添加到列表中。然后,创建一个长度为 20 的新数组,并将所有元素从第一个数组复制到新数组。
    • 哦,是的,对不起,我弄错了。我应该说的是,Array 的大小始终保持 10,对。谢谢你。我现在很清楚了。
    • 请注意,实际初始长度可能与 10 不同,新长度可能不是初始长度的 2 倍。这只是说明机制的一个例子。
    【解决方案2】:

    从末尾删除元素时不会创建新数组,从开头删除元素时也不会创建新数组,但是如果最后一个元素比第一个元素移动得更多一,还有你的时差。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-02-24
      • 2016-07-23
      • 1970-01-01
      • 2011-05-13
      • 2011-06-24
      • 1970-01-01
      相关资源
      最近更新 更多