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();
повторяется для каждого дополнительного атрибута. Для ints.hashCode() может быть опущен.)
Это кажется прекрасным, но для выбора 31 для простого. Вероятно, это взято из реализации hashCode Java String, которая использовалась по причинам производительности, которые давно прошли после внедрения аппаратных множителей. Здесь у вас много столкновений hashcode для небольших значений я и j: например (0,0) и (-1,31) имеют одинаковое значение. Я думаю, что это Bad Thing (TM), так как небольшие значения происходят часто. Для String.hashCode вы также найдете много коротких строк с одним и тем же хэш-кодом, например "Ca" и "DB". Если вы принимаете большое простое, эта проблема исчезает, если вы выберете правое правое.
Итак, мой вопрос: что хорошего выбора? Какие критерии вы применяете для его поиска?
Это подразумевается как общий вопрос - поэтому я не хочу давать диапазон для я и j. Но я полагаю, что в большинстве приложений относительно небольшие значения встречаются чаще, чем большие. (Если у вас большие значения, выбор премьер-версии, вероятно, неважен.) Это может не сильно повлиять, но лучший выбор - простой и понятный способ улучшить это - так почему бы не сделать это? Commons lang HashCodeBuilder также предлагает любопытно небольшие значения.
( Разъяснение: это не дубликат Почему Java hashCode() в String использует 31 как множитель?, так как мой вопрос не имеет отношения к истории 31 в JDK, но о том, что будет лучшим значением в новом коде с использованием одного и того же базового шаблона. Ни один из ответов там не пытается ответить на этот вопрос.)