2012-06-28 3 views
1

В настоящее время я работаю над сравнением двух сложных объектов одного типа с несколькими полями, состоящими из структур данных пользовательских типов объектов. Предполагая, что ни один из пользовательских объектов не переопределяет метод hashCode(), если я сравниваю хэш-коды каждого поля в объектах, и они окажутся одинаковыми, я уверен, что содержание сравниваемых объектов равно 100% тоже самое? Если нет, какой метод вы бы рекомендовали сравнить два объекта, предполагая, что я не могу использовать какие-либо внешние библиотеки.Является ли метод hashCode() Java надежной мерой равенства объектов?

ответ

8

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

Подумайте об этом так: есть только 2 Возможные хэш-коды. Сколько возможных различных объектов существует для типа String, в качестве примера? Это гораздо больше. Поэтому не менее двух неравные строки должны совместно использовать один и тот же хеш-код.

Eric Lippert writes well about hash codes - по общему признанию, с точки зрения .NET, но принципы одинаковы.

+0

Привет, поэтому мне нужно написать метод equals для более 70 полей классов, причем многие из них являются структурами данных пользовательских объектов? Нет другого пути вокруг него? – LucasSeveryn

+3

Если два объекта, которые нужно сравнить, считаются равными, если все эти 70 полей равны, то нет другого пути вокруг него. Обратите внимание, что среда IDE, такая как Eclipse, может автоматически генерировать для вас метод hashCode и 'equals'. – Jesper

+0

Итак, для небольшого объекта мы ничего не получаем от использования hashcode? – BlueSky

2

Нет, отсутствие hashCode() столкновения только означает, что объекты могли быть идентичными, это никогда гарантии.

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

Кроме того, если ваши пользовательские типы не имеют hashCode() реализацию, то это значение совершенно бесполезно для сравнения содержание объекта, потому что это будет identityHashCode().

0

Если вы не переопределили метод hashCode(), все ваши объекты неравны. Переопределяя это, вы предоставляете логику сравнения. Помните, что если вы переопределите hashCode(), вы определенно должны переопределить equals(). EDIT: все еще может быть collisionm, конечно, но если вы не переопределили equal(), ваши объекты будут сравниваться по ссылке (объект равен самому себе).

0

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

Однако фактическая спецификация Object.hashCode() не содержит гарантий и не должна использоваться для этой цели в любой разумной или хорошо написанной части кода.

Я бы предложил использовать hashCode и равные строители, доступные в библиотеке сообщества Apache, или если вы действительно не можете использовать бесплатные внешние библиотеки, просто посмотрите на них для вдохновения. Лучший метод использования полностью зависит от того, что «равно» на самом деле означает в контексте вашего домена приложения.

Смежные вопросы