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)}并使其有资格进行垃圾收集?
clear()
的O(n)表现对我来说似乎不太好,或者我错过了什么?
答案 0 :(得分:9)
按照它们的方式执行操作可让您重用数组而无需重新分配其后备存储。如果你想重新分配数组,你可以自己完成,因为ArrayList
的表示主要由它的后备存储组成。
如果他们作为一个整体发布了数组,那么在调用clear()
和重新分配ArrayList
本身之间几乎没有什么区别。现在,他们为您提供了重新选择阵列或将其替换为全新阵列的选择。
答案 1 :(得分:3)
此实现允许在不重新分配的情况下重用数组。 Allocating an array in java can be O(n) anyway因为JVM会将所有元素初始化为默认值。
答案 2 :(得分:2)
如果你清楚()一个ArrayList,你显然打算重用它 - 所以任何重用都可能在其中具有相同数量的对象。因此,避免调整大小操作似乎是一个好主意。
另外,请记住,JIT编译在这里很重要,可能很多 - 该循环将非常缓存友好&amp;单个操作非常便宜 - 在编译的情况下,每个操作可能只需要一个机器指令。
答案 3 :(得分:0)
这与clear() impl in Java's LinkedList Generational Garbage Collection的原因相同。
这个ArrayList和支持数组更有可能被提升到“老一代”,在那里它可以保留更有可能在年轻一代中的数组索引所引用的对象。将所有索引设置为null允许在收集后备数组之前收集这些较年轻的对象。