hashCode()
Метод класса Boolean реализуется следующим образом:
public int hashCode() {
return value ? 1231 : 1237;
}
Почему он использует 1231 и 1237? Почему не что-нибудь еще?
hashCode()
Метод класса Boolean реализуется следующим образом:
public int hashCode() {
return value ? 1231 : 1237;
}
Почему он использует 1231 и 1237? Почему не что-нибудь еще?
Ответы:
1231 и 1237 - это всего лишь два (достаточно больших) произвольных простых числа . Подойдут любые другие два больших простых числа.
Почему простые числа?
Предположим на секунду, что мы выбрали составные числа (не простые числа), скажем, 1000 и 2000. При вставке логических значений в хеш-таблицу значения true и false перейдут в сегмент 1000 % N
соответственно 2000 % N
(где N
- количество сегментов).
Теперь обратите внимание, что
1000 % 8
такое же ведро как 2000 % 8
1000 % 10
такое же ведро как 2000 % 10
1000 % 20
такое же ведро как 2000 % 20
другими словами, это привело бы к множеству столкновений .
Это потому, что факторизация 1000 (2 3 , 5 3 ) и факторизация 2000 (2 4 , 5 3 ) имеют так много общих факторов. Таким образом, выбираются простые числа, поскольку они вряд ли будут иметь общие множители с размером корзины.
Почему большие простые числа. Разве 2 и 3 не подойдут?
При вычислении хэш-кодов для составных объектов обычно добавляют хэш-коды для компонентов. Если в хеш-наборе с большим количеством сегментов используются слишком маленькие значения, существует риск получить неравномерное распределение объектов.
Имеют ли значение столкновения? В любом случае логические значения имеют два разных значения?
Карты могут содержать логические значения вместе с другими объектами. Кроме того, как указывает Drunix, распространенным способом создания хэш-функций составных объектов является повторное использование реализаций хэш-кода подкомпонентов, и в этом случае хорошо возвращать большие простые числа.
Связанные вопросы:
2*1231 = 2462
ведра. Являются ли столкновения проблемой в такой ситуации?