В Eclipse 3.5 есть очень хорошая функция для создания функций Java hashCode (). Например, он будет генерировать (немного укороченный :)
class HashTest {
int i;
int j;
public int hashCode() {
final int prime = 31;
int result = prime + i;
result = prime * result + j;
return result;
}
}
(Если в классе больше атрибутов, result = prime * result + attribute.hashCode();
повторяется для каждого дополнительного атрибута. Для целых значений .hashCode () можно опустить.)
Это кажется прекрасным, но для выбора 31 для прайма. Вероятно, это взято из реализации hashCode Java String, который использовался по соображениям производительности, которые давно исчезли после введения аппаратных умножителей. Здесь у вас много конфликтов хэш-кода для небольших значений i и j: например, (0,0) и (-1,31) имеют одно и то же значение. Я думаю, что это Плохая Вещь (TM), поскольку небольшие значения встречаются часто. Для String.hashCode вы также найдете много коротких строк с тем же хэш-кодом, например «Ca» и «DB». Если вы возьмете большое простое число, эта проблема исчезнет, если вы выберете правильное простое число.
Итак, мой вопрос: какое простое решение выбрать? Какие критерии вы применяете, чтобы его найти?
Это общий вопрос, поэтому я не хочу давать диапазон для i и j. Но я полагаю, что в большинстве приложений относительно небольшие значения встречаются чаще, чем большие. (Если у вас большие значения, выбор простого числа, вероятно, не имеет значения.) Это может не иметь большого значения, но лучший выбор - это простой и очевидный способ улучшить это - так почему бы не сделать это? Commons lang HashCodeBuilder также предлагает любопытно маленькие значения.
(Уточнение: это не дубликата Почему Java hashCode () в String использует 31 в качестве множителя?, поскольку мой вопрос не касается истории 31 в JDK, а о том, что было бы лучше в новом коде, использующем тот же базовый шаблон. Ни один из приведенных здесь ответов не пытается ответить на этот вопрос.)
*31
можно сделать с помощью одной инструкции. На самом деле, достаточно любого нечетного числа, простого или нет. - person Tom Hawtin - tackline   schedule 03.12.2009p = (2^n-1)
поддаются оптимизацииx * p = (p << n) - p
, которую обычно делает компилятор. Из Джошуа Блоха, Эффективная Java, глава 3, пункт 9. SO question stackoverflow.com/questions/299304/ - person corsiKa   schedule 16.02.20112^n-1
, prime, smallish .. это дает 31. - person J-16 SDiZ   schedule 27.11.2014