将元素添加到Java ArrayList的末尾应该花费O(1)时间。但是,向中间添加元素必须将右半部分移动一个以维持顺序。这应该花费O(n)时间(实际上O(n / 2)简化为O(n))。
我的问题是:
在原始内存中,这个移位会移动驻留在ArrayList中的对象本身,还是只移动指向它们的引用?
无论是哪种,时间复杂度都是相同的,但开销可能会有所不同。将一堆巨大的物体移到一边为中间的一个腾出空间可能比在内存中移动一些大小的引用要大得多。
所以:
这是什么?我倾向于猜测它是被移位的引用,因为Java List保存对堆上对象的引用,这些对象可能在内存中的任何“顺序”。
我对上述所有内容的任何错误?
我问的原因纯粹是理论上的。我只是想知道内存中发生了什么,如果大量的对象被交换,或者它只是被拖拽的引用。感谢。
(注意:这几乎是我今天早些时候提到的this question的后续行动。)
答案 0 :(得分:4)
在原始记忆中,这种移动是否会移动物体本身 驻留在ArrayList中,还是只是指向它们的引用?
简短回答没有移动真实对象,只有引用被复制到具有新索引的arraylist的内部数组中。
这是什么?我倾向于猜测这是参考文献 移位,因为Java List保存对堆上对象的引用 可能在记忆中的任何“顺序”。
Arraylist在内部使用数组。对象的引用在数组中维护。这些引用所指向的对象可以在存储器中的任何位置,也不一定按顺序排列。它只是arraylist内部数组中的引用,它有助于使用数组索引获取对象。
答案 1 :(得分:0)
仅使用ArrayList类
中的代码来证实上面的语句 @Override public void add(int index, E object) {
Object[] a = array;
int s = size;
if (index > s || index < 0) {
throwIndexOutOfBoundsException(index, s);
}
if (s < a.length) {
System.arraycopy(a, index, a, index + 1, s - index);
} else {
// assert s == a.length;
Object[] newArray = new Object[newCapacity(s)];
System.arraycopy(a, 0, newArray, 0, index);
System.arraycopy(a, index, newArray, index + 1, s - index); //shifting to right
array = a = newArray;
}
a[index] = object;
size = s + 1;
modCount++;
}