Почему HashMap требует, чтобы начальная емкость была степенью два?
Я просматривал исходный код HashMap Java, когда увидел следующее
//The default initial capacity - MUST be a power of two.
static final int DEFAULT_INITIAL_CAPACITY = 16;
Мой вопрос заключается в том, почему это требование существует в первую очередь? Я также вижу, что конструктор, который позволяет создавать хэш-карту с пользовательской емкостью, преобразует ее в степень два:
int capacity = 1;
while (capacity < initialCapacity)
capacity <<= 1;
Почему емкость всегда должна быть силой двух?
Кроме того, когда выполняется автоматический повторный хэш, что именно происходит? Хэш-функция тоже изменилась?
2 ответов:
Карта должна определить, какой внутренний индекс таблицы использовать для любого данного ключа, сопоставляя любое значение
int(может быть отрицательным) значению в диапазоне[0, table.length). Когдаtable.lengthесть степень двойки, то это можно сделать действительно дешево - и есть, вindexFor:static int indexFor(int h, int length) { return h & (length-1); }При другой длине таблицы вам нужно вычислить остаток и убедиться, что он неотрицателен . Это определенно микро-оптимизация, но, вероятно, допустимая:)
Мне не совсем понятно, что вы имеете в виду. Используются одни и те же хэш-коды (потому что они просто вычисляются вызовомТакже, когда автоматический перефразирование является исполнено, что именно происходит? Хэш-функция тоже изменилась?
hashCodeдля каждого ключа), но они будут распределены по-разному в таблице из-за изменения длины таблицы. Например, когда длина таблицы равна 16, хэш-коды 5 и 21 в конечном итоге сохраняются в записи таблицы 5. Когда длина таблицы увеличивается до 32, они будут находиться в разных записях.
Идеальная ситуация на самом деле использует размеры простых чисел для резервного массива
HashMap. Таким образом, ваши ключи будут более естественно распределены по всему массиву. Однако это работает с разделением mod, и эта операция становилась все медленнее и медленнее с каждым выпуском Java. В некотором смысле, сила подхода 2-это худший размер таблицы, который вы можете себе представить, потому что при плохих реализациях хэш-кода более вероятно производить ключевые коллозии в массиве.Поэтому вы найдете другой очень важный метод в реализации Java
HashMap, который являетсяhash(int), который компенсирует плохие хэш-коды.
Comments