【问题标题】:Why ArrayList.trimToSize is not Called Automatically in ArrayList Class?为什么 ArrayList 类中不自动调用 ArrayList.trimToSize?
【发布时间】:2022-01-13 15:19:30
【问题描述】:

它在调用ArrayList.add()后删除列表中多余的未使用位置

但是为什么在 ArrayList 类中没有自动调用呢?

【问题讨论】:

  • 因为当你添加另一个东西时,你必须再次放大列表。 ArrayList 已摊销线性插入时间,因为它不必每次添加到列表时都调整列表大小。

标签: java arraylist


【解决方案1】:

如果添加时 ArrayList 已满,则必须将其内容复制到一个新的更大的数组中。基本上:

void add(Object newItem) {
  if (size == array.length) {
    array = Arrays.copyOf(array, newSize);
  }
  array[size++] = newItem;
}

问题是你如何选择newSize:你显然可以选择一个刚好大到足以容纳新项目的值,即

newSize = size + 1;

但您必须将 size 项复制到新数组中。

如果您以这种方式将 10 项添加到 ArrayList,您将复制 0 项、1 项、2 项、3 项.... 9 项:以这种方式添加的成本是二次方的。

相反,采用不同的策略:将列表的大小增加一些乘法因子,例如2:

* (List size initially 1)
* Add item 1
* Copy array into length-2 array
* Add item 2
* Copy array into length-4 array
* Add item 3
* Add item 4
* Copy array into length-8 array
* Add item 5
* Add item 6
* Add item 7
* Add item 8
* Copy array into length-16 array
* Add item 9
* Add item 10

所以,随着数组变大,你做的副本会越来越少。事实上,数学计算表明,以这种方式添加和调整大小是线性,而不是二次的。

所以,当然,您最终可能会得到一个太大的后备数组;当您完成向其中添加内容时,请务必将其修剪到容量。但在时间方面不是自动修剪它更有效。

【讨论】:

    猜你喜欢
    • 2011-04-16
    • 2013-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-10
    • 1970-01-01
    • 1970-01-01
    • 2015-11-17
    相关资源
    最近更新 更多