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

Каков трюк метода hash() в реализации Java HashMap?

Возможный дубликат:
Понимание странной хэш-функции Java

static int hash(int h) {   
    // This function ensures that hashCodes that differ only by   
    // constant multiples at each bit position have a bounded   
    // number of collisions (approximately 8 at default load factor).   
    h ^= (h >>> 20) ^ (h >>> 12);   
    return h ^ (h >>> 7) ^ (h >>> 4);   
} 

Я не совсем понимаю принцип алгоритма этой реализации. Любое объяснение или любое другое сообщение, на которое я могу ссылаться? Спасибо!

UPDATE

Спасибо всем за ответы и комментарии. На самом деле я понимаю, как работает хеш, но не знаю, почему этот код обеспечит a bounded number of collisions, как говорится в комментарии. Есть ли теоретическая проверка?

4b9b3361

Ответ 1

Основная цель - генерировать очень разные значения для аналогичных входных параметров и минимизировать количество столкновений. http://en.wikipedia.org/wiki/Hash_function

Эта реализация является лишь одним из удовлетворительных вариантов многих возможных функций.

Ответ 2

Эта функция помогает лучше избегать столкновений в HashMap.

Если у вас хорошая реализация hashCode, вы все равно можете получить столкновение только потому, что вы берете hashCode % size для обнаружения ведра для объекта.

Пример:

Предположим, что размер вашего HashMap равен 20.

  • Вы рассчитали hashCode() для object1 и получите 401. Ведро 401 % 20 = 1.
  • Вы рассчитали hashCode() для object2 и получите 3601. Ведро 3601 % 20 = 1
  • Вы рассчитали hashCode() для object3 и получите 1601. Ведро 1601 % 20 = 1.

Таким образом, даже у вас есть три разных хэш-кода, вы получаете одно ведро для всех трех объектов, это означает сложность вашего HashMap O(n) вместо O(1).

Если мы применим функцию hash ко всем полученным хэш-кодам, получим

  • hash = 395, bucket = 395 % 20 = 15
  • hash = 3820, bucket = 3820 % 20 = 0
  • hash = 1577, bucket = 1577 % 20 = 17

Очистите, что, применяя hash в качестве дополнительного шага, мы получаем три разных ведра, которые сохраняют постоянный доступ времени к вашему объекту.

Ответ 3

оператор → > является битдвигом, но обрабатывается как unsigned.

^ - XOR (eXclusive или)

Итак, строка

h ^= (h >>> 20) ^ (h >>> 12);   

означает xor оригинал с h бит-бит 20 бит, XOR с h сдвинутыми 12 бит

то

h ^ (h >>> 7) ^ (h >>> 4); 

h сверху, xor h сдвинул 7 бит, xor h сдвинул 4 бита. Im не на 100% уверен, почему он настроен таким образом, хотя