2013-08-14 3 views
7

http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/ArrayList.java#473Почему java.util.Arraylist # ясно реализован так, как это было в OpenJDK?

public void clear() { 
    modCount++; 

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

    size = 0; 
} 

Мой вопрос, почему они должны сделать цикл через вспомогательный массив {O (п)}, чтобы каждый элемент, имеющих право на сбор мусора, когда они могли просто быть инициализируется массив подкладочный, отбрасывая ссылки на весь массив в целом {O (1)} и делая его пригодным для сбора мусора? Производительность O (n) для clear() кажется мне не очень приятной или я чего-то не хватает?

+2

возможно дубликат [list.clear() против списка = новый ArrayList ();] (http://stackoverflow.com/questions/6961356/list-clear-vs-list-new-arraylistinteger) – Tala

+0

Я не подумайте, что это дубликат. – nawfal

ответ

9

Выполнение этого способа, который они сделали, позволяет повторно использовать массив без перераспределения его резервного хранилища. Если вы хотите перераспределить массив, вы могли бы сделать это сами, так как представление ArrayList в основном состоит из его резервного хранилища.

Если они выпустили массив в целом, между вызовом и перераспределением самого ArrayList было бы очень мало. Теперь они дают вам возможность выбирать между повторным использованием массива или заменой его совершенно новым.

+0

Почти так же можно было бы сделать что-то вроде: 'for (loop_through_list as e) {e = null}' // псевдокод –

+1

@SayoOladeji Правильно, но для этого потребуется цикл и потребуется дополнительный аргумент проверяя каждый раз, когда вы устанавливаете элемент в «null». Когда вы делаете 'new ArrayList()', вы торгуете одну строку для одной строки, а не одну строку для цикла. – dasblinkenlight

+0

Теперь у меня совершенно другая перспектива невинного вида 'def arr = new Object [n]' Спасибо! –

3

Эта реализация позволяет повторно использовать массив без перераспределения. Allocating an array in java can be O(n) anyway, поскольку JVM инициализирует все элементы по умолчанию.

2

Если вы поняли() используя ArrayList, вы, очевидно, намерены его повторно использовать, и поэтому любое повторное использование может иметь одинаковое количество объектов в нем. Поэтому избегать операций изменения размера кажется хорошей идеей.

Также, голые в виду, что вопросы JIT компиляции здесь, потенциально очень много - что цикл будет чрезвычайно кэш дружественных & отдельные операции очень дешево - вероятно, только одна машинная команда для каждого в компилируемый случае ,

0

По той же причине, что и clear() impl in Java's LinkedList, которая является Java Generational Garbage Collection.

Этот массив ArrayList и поддерживающий массив, скорее всего, будут продвигаться в «старое поколение», где это возможно для того, чтобы удерживать объекты, на которые ссылаются индексы массива, которые, скорее всего, будут в молодоем поколении. Установка всех индексов в нуль позволяет собирать младшие объекты до сбора массива подложки.

Смежные вопросы