ArrayList поддерживает массив позади сцены. Я хочу углубиться в исходный код java.util.ArrayList
и java.util.LinkedList
.
Прежде всего, ArrayList поддерживает массив за кулисами. Когда вы создаете экземпляр ArrayList, он создает массив размером 10 и растет, пока вставлены элементы. Размер увеличивается до 3 (размер)/2 +1
Вот исходный код.
Размер по умолчанию для сортировки. Посмотрите на constructer code.
public ArrayList() {
this(10);
}
его размер увеличивается до 3 (размер)/2 + 1 здесь является source code. ArrayList#ensureCapacity метод называется INSITE ArrayList#add
public void ensureCapacity(int minCapacity) {
modCount++;
int oldCapacity = elementData.length;
if (minCapacity > oldCapacity) {
Object oldData[] = elementData;
int newCapacity = (oldCapacity * 3)/2 + 1;
if (newCapacity < minCapacity)
newCapacity = minCapacity;
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
}
При удалении какой-либо элемент из ArrayList. Он удаляется из списка, а другие элементы списка перемещаются вниз до места удаленных объектов. Обратите особое внимание, ссылка на этот объект установлена равной нулю, и объект становится доступным для GC, но для ArrayList все еще имеется ссылка. Размер массива за ArrayList такой же.
Вот source code
public E remove(int index) {
rangeCheck(index);
modCount++;
E oldValue = elementData(index);
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // Let gc do its work
return oldValue;
}
Как ответил Джон Скит, когда элемент удаляется следующий элемент для удаленного элемента будет находиться в удаленном месте пунктов.
Однако выделенное пространство памяти остается неизменным после удаления. java.util.LinkedList - эта проблема. Все элементы внутри LinkedList динамически распределяются и освобождаются (это, конечно же, работа GC)
java.util.LinkedList поддерживает doubly linked list за кулисами. Каждая операция добавления и удаления изменяет пространство памяти, используемое LinkedList. Элемент удален, а ссылка на элемент из предыдущего и последующих элементов обновляется.
Here is the source code :
private Entry<E> entry(int index) {
if (index < 0 || index >= size)
throw new IndexOutOfBoundsException("Index: "+index+
", Size: "+size);
Entry<E> e = header;
if (index < (size >> 1)) {
for (int i = 0; i <= index; i++)
e = e.next;
} else {
for (int i = size; i > index; i--)
e = e.previous;
}
return e;
}
Я предполагаю, что GC собирает предметы, как только он удаляется, я знаю, он не уверен. Но удаленная ячейка памяти является кандидатом в GC. Будьте осторожны с ссылкой на объект и сам объект.
Как ArrayList, так и LinkedList удаляют элементы, в то время как ArrayList по-прежнему сохраняет ссылку на типы объектов и пространство памяти для примитивных типов, связанный список также удаляет ссылки и пространство памяти. По крайней мере, ссылки и память также будут иметь право на GC.
Еще раз, удивительный ответ .. Ура! – Dropout
ли массив позади 'ArrayList' также сокращается при удалении элементов? – erencan
@erencan: Не так далеко, насколько я знаю, но зацикленные элементы заполняются «нулем», чтобы избежать проблем с GC. Вы можете вызвать 'trimToSize' после этого, если это необходимо, но это редко полезно IME. –