Я изучаю Правило 9, Эффективная Java [Всегда переопределяйте hashcode (), когда переопределяете равно].
У меня есть несколько вопросов по поводу замечаний автора:
- Автор говорит:
На шаге 1 используется ненулевое начальное значение, поэтому на хеш-значение будут влиять начальные поля, хеш-значение которых, вычисленное на шаге 2.a, равно нулю. Если бы ноль использовался в качестве начального значения на шаге 1, на общее хеш-значение не повлияли бы какие-либо такие начальные поля, что могло бы увеличить коллизии. Значение 17 произвольно.
Шаг 2.а:
Для каждого значимого поля f в вашем объекте (то есть каждого поля, учитываемого методом equals) выполните следующие действия: a. Вычислите хэш-код int c для поля:
я. Если поле является логическим, вычислить (f? 1: 0).
II. Если поле является байтовым, символьным, коротким или целым, compute (int) f.
iii. Если поле длинное, вычислите (int) (f ^ (f ››› 32)).
iv. Если поле является плавающим, вычислите Float.floatToIntBits (f).
v. Если поле является двойным, вычислите Double.doubleToLongBits (f), а затем хешируйте полученную длину, как на шаге 2.a.iii.
vi. Если поле является ссылкой на объект и метод equals этого класса сравнивает поле, рекурсивно вызывая equals, рекурсивно вызывает hashCode для поля. Если требуется более сложное сравнение, вычислите «каноническое представление» для этого поля и вызовите hashCode для канонического представления. Если значение поля равно нулю, верните 0 (или другую константу, но обычно 0).
vii. Если поле является массивом, относитесь к нему так, как если бы каждый элемент был отдельным полем. То есть вычислить хэш-код для каждого значимого элемента, рекурсивно применяя эти правила, и объединить эти значения на шаге 2.b. Если каждый элемент в поле массива имеет значение, вы можете использовать один из методов Arrays.hashCode, добавленных в версии 1.5.
Предположим, результат рассчитывается как:
result = 31 * result + areaCode;
result = 31 * result + prefix;
result = 31 * result + lineNumber;
В случае, если начальное значение результата равно 0, а все указанные выше поля равны 0, результат останется 0. Но, даже если результат изначально не равен 0, результат будет равняться одной и той же константе каждый раз, когда начальные поля равны 0, что будет : 31 * (31 * (31 * 17)). Как это значение поможет уменьшить количество столкновений?
- В последнем абзаце говорится, что:
Многие классы в библиотеках платформы Java, такие как String, Integer и Date, включают в свои спецификации точное значение, возвращаемое их методом hashCode как функцию значения экземпляра. Как правило, это не очень хорошая идея, так как это сильно ограничивает ваши возможности по улучшению хеш-функции в будущих выпусках. Если вы оставите детали хэш-функции неуказанными и будет обнаружен недостаток или обнаружена лучшая хеш-функция, вы можете изменить хеш-функцию в следующем выпуске, будучи уверенным, что никакие клиенты не зависят от точных значений, возвращаемых хеш-функцией.
Что он имеет в виду, говоря, что точное значение, возвращаемое hashCode, является функцией значения экземпляра?
Заранее благодарю за любую помощь.