hashCode()
Метод класу Boolean реалізується в такий спосіб:
public int hashCode() {
return value ? 1231 : 1237;
}
Чому він використовує 1231 та 1237? Чому б не щось інше?
hashCode()
Метод класу Boolean реалізується в такий спосіб:
public int hashCode() {
return value ? 1231 : 1237;
}
Чому він використовує 1231 та 1237? Чому б не щось інше?
Відповіді:
1231 і 1237 - це лише два (досить великі) довільні прості числа . Будь-які інші два великі прості числа були б чудовими.
Чому праймес?
Припустимо, на секунду, що ми вибрали складені числа (non-primes), скажімо, 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
відра. Чи зіткнення є проблемою в такій ситуації?