Подтвердить что ты не робот

Вы можете просто вернуть значение hashCode() поля в методе hashCode()?

При просмотре большой базы кода я часто сталкивался с такими случаями:

@Override
public int hashCode() 
{
    return someFieldValue.hashCode();
}

где программист вместо генерации собственного уникального хэш-кода для класса просто наследует хэш-код из значения поля. Чувство моего кишечника (которое также может быть проблемой пищеварения) говорит мне, что это неправильно, но я не могу на него надавить. Какие проблемы могут возникнуть, если таковые имеются, с такой реализацией?

4b9b3361

Ответ 1

Это нормально, если вы хотите хэш-объект на основе одного свойства.

Например, в классе Person у вас может быть свойство ID, которое однозначно идентифицирует Person, поэтому hashCode() of Person может просто быть хэшем этого идентификатора.

Кроме того, hashCode() связан с реализацией equals. Если два объекта равны, они должны иметь один и тот же hashCode (противоположное не должно быть истинным - два не равных объекта могут по-прежнему иметь один и тот же хэш-код). Поэтому, если равенство определяется одним свойством (таким как уникальный идентификатор), метод hashCode должен также использовать только одно свойство.

Это можно увидеть в JavaDoc hashCode:

Общий контракт hashCode:

  • Всякий раз, когда он вызывается одним и тем же объектом более одного раза во время выполнения приложения Java, метод hashCode должен последовательно возвращать одно и то же целое число, если информация, используемая при равных сравнениях с объектом, не изменяется. Это целое число не должно оставаться согласованным с одним исполнением приложения на другое выполнение того же приложения.
  • Если два объекта равны в соответствии с методом equals (Object), то вызов метода hashCode для каждого из двух объектов должен приводить к одному и тому же целочисленному результату.
  • Не требуется, чтобы, если два объекта неравны в соответствии с методом equals (java.lang.Object), то вызов метода hashCode для каждого из двух объектов должен производить различные целочисленные результаты. Тем не менее, программист должен знать, что получение отдельных целых результатов для неравных объектов может улучшить производительность хеш-таблиц.

Ответ 2

С технической точки зрения вы можете вернуть любое согласованное число из hashCode , даже постоянное значение. Единственное требование, которое заключает контракт на вас, состоит в том, что равные объекты должны возвращать один и тот же хэш-код:

Если два объекта равны в соответствии с методом equals (Object), то вызов метода hashCode для каждого из двух объектов должен приводить к одному и тому же целочисленному результату.

Теоретически, если все объекты возвращают, скажем, ноль для своих hashCode , контракт формально выполняется. Однако это делает hashCode совершенно бесполезным.

Реальный вопрос заключается в том, следует ли вам это делать или нет. Ответ зависит от того, насколько уникальным является поле, хэш-код которого вы возвращаете. Необязательно возвращать hashCode уникального идентификатора объекта для объекта hashCode . С другой стороны, если значительная часть объектов имеет значение sane значения someFieldValue, вам будет лучше использовать другую стратегию для создания хэш-кода вашего объекта.

Ответ 3

hashCode() должен идти с equals().

Если единственным свойством, определяющим равенство, является, например, идентификатор, вы должны заботиться о том, чтобы ваши хэш-коды были равны, когда идентификатор равен. Самый простой способ добиться этого - взять hashCode() вашего идентификатора.

Ответ 4

Это прекрасно, если вы действительно хотите однозначно идентифицировать свой объект с помощью этого единственного свойства. Вот статья которая объясняет, что такое идентификация объекта.

Как указано в документации Object, ваши equals() и hashCode() должны включать одни и те же свойства, обязательно убедитесь, что.

Итак, это означает, что вы должны задать себе вопрос: действительно ли я хочу, чтобы объекты были равны, если только это единственное свойство равно?

Наконец, обратите внимание, что при подклассификации объектов с пользовательской реализацией equals() и hashCode(), если вы хотите добавить свойства к идентификатору объекта, вы нарушите требование, чтобы a.equals(b) == b.equals(a) (чтобы понять, почему это это не так, поскольку a является суперклассом, а b является подклассом.

Ответ 5

да, вы можете сделать это технически, для этого вам понадобится не-примитивный somefieldValue.