Подтвердить что ты не робот

Является ли Java HashMap.clear() и remove() эффективной?

Рассмотрим следующий код HashMap.clear():

 /**
 * Removes all of the mappings from this map.
 * The map will be empty after this call returns.
 */
public void clear() {
    modCount++;
    Entry[] tab = table;
    for (int i = 0; i < tab.length; i++)
        tab[i] = null;
    size = 0;
}

Кажется, что внутренний массив (table) объектов Entry никогда не сжимается. Поэтому, когда я добавляю к карте 10000 элементов, и после этого вызова map.clear(), он будет содержать 10000 нулей в нем внутреннего массива. Итак, мой вопрос: как JVM обрабатывает этот массив ничего, и, следовательно, эффективна HashMap?

4b9b3361

Ответ 1

Идея состоит в том, что clear() вызывается только тогда, когда вы хотите повторно использовать HashMap. Повторное использование объекта должно выполняться только по той же причине, что и раньше, поэтому есть вероятность, что у вас будет примерно одинаковое количество записей. Чтобы избежать ненужного сокращения и изменения размера Map, емкость сохраняется одинаковой при вызове clear().

Если все, что вы хотите сделать, это сбросить данные в Map, тогда вам не нужно (и на самом деле не следует) называть clear() на нем, но просто очистить все ссылки на Map себя, в в этом случае в конечном итоге будет собран мусор.

Ответ 2

Посмотрев на исходный код, он выглядит как HashMap никогда не сжимается. Метод resize вызывается для удвоения размера, когда это требуется, но не имеет ничего ala ArrayList.trimToSize().

Если вы используете HashMap таким образом, что он растет и сильно сокращается, вы можете просто создать новый HashMap вместо вызова clear().

Ответ 3

Вы правы, но учитывая, что увеличение массива является гораздо более дорогостоящей операцией, для HashMap неразумно думать "когда пользователь увеличил массив, скорее всего, ему понадобится массив такого размера позже", и просто оставьте массив, а не уменьшайте его и рискуете, чтобы потом дорого его расширять позже. Полагаю, это эвристический подход - вы тоже можете защищать и наоборот.

Ответ 4

Еще одна вещь, которую следует учитывать, состоит в том, что каждый элемент в table является просто ссылкой. Установка этих записей в значение null приведет к удалению ссылок из элементов вашего Map, которые затем будут бесплатными для сбора мусора. Так что это не так, как будто вы вообще не освобождаете память.

Однако, если вам нужно освободить даже память, используемую самим Map, тогда вы должны отпустить ее в соответствии с предложением Йоахима Зауэра.