7

http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/ArrayList.java#473

public void clear() {
    modCount++;

    // Let gc do its work
    for (int i = 0; i < size; i++)
        elementData[i] = null;

    size = 0;
}

我的问题是,为什么他们必须在支持数组 { O(n) } 中进行循环以使每个元素都符合垃圾收集条件,而他们本可以重新初始化支持数组,丢弃对整个数组的引用 { O(1) } 并使其有资格进行垃圾收集?O(n) 的表现对clear()我来说似乎不太好,还是我错过了什么?

4

4 回答 4

9

按照他们的方式进行操作可以让您重用阵列,而无需重新分配其后备存储。如果您想重新分配数组,您可以自己完成,因为 的表示ArrayList主要由其后备存储组成。

clear()如果他们将数组作为一个整体释放,那么调用和重新分配ArrayList本身就没有什么区别了。现在,您可以选择重新使用阵列还是用全新的阵列替换它。

于 2013-08-14T13:13:40.033 回答
3

此实现允许数组重用而无需重新分配。无论如何,在 java 中分配一个数组可能是 O(n),因为 JVM 会将所有元素初始化为默认值。

于 2013-08-14T13:15:22.517 回答
2

如果您清除()一个 ArrayList,那么您显然打算重用它 - 因此任何重用都可能包含相同数量的对象。所以避免调整大小操作似乎是个好主意。

此外,请记住 JIT 编译在这里很重要,可能很多 - 该循环将非常缓存友好并且各个操作非常便宜 - 在编译的情况下可能只是每个机器指令。

于 2013-08-14T13:22:30.530 回答
0

这与Java 的 LinkedList中的 clear() impl 相同,即 Java 分代垃圾收集

这个 ArrayList 和后备数组更有可能被提升到“老一代”,在那里它可以保留由更可能在年轻一代中的数组索引引用的对象。将所有索引设置为 null 允许在收集后备数组之前收集那些较年轻的对象。

于 2017-05-26T17:16:41.027 回答