Два экземпляра, имеющие один и тот же хэш-код, но не равный
Я читал приведенный ниже параграф из статьи под названием Теория и практика Java: Хеширование - Определение hashCode() и equals() эффективно и правильно
Определение равенстваКласс Object имеет два метода для выводов о идентичности объекта: equals() и hashCode(). В если вы переопределите один из этих методов, вы должны переопределить оба, поскольку между ними существуют важные отношения, которые должны быть поддерживается. В частности, если два объекта равны в соответствии с equals(), они должны иметь одинаковое значение hashCode() (хотя обратное вообще не верно). [выделено мной мной]
Мой вопрос касается последнего бита абзаца "хотя обратное вообще не верно". Как возможно, чтобы два разных экземпляра класса имели один и тот же хэш-код, но не были равны?
Ответы
Ответ 1
В простых терминах hashcode() - это функция для генерации хешей по какой-либо формуле, поэтому могут быть некоторые столкновения, два разных значения могут оказаться одинаковыми хэш-кодами.
Если я просто вычислил хэш-код, приняв mod на 6, тогда два разных значения могут иметь один и тот же хэш-код.
Ответ 2
Вы можете рассмотреть hashes to be a bucket
..
- Если два объекта равны, они войдут в то же самое ведро (имеют одинаковые хэш-коды)
- Но если два объекта переходят в один и тот же массив (имеют один и тот же хэш-код), это не означает, что они должны быть равны
- Также обратите внимание, что если два объекта не равны, даже тогда они могут иметь один и тот же хэш-код. Очевидно, что это указывает на две вышеописанные точки.
Итак, hashcode - это не что иное, как хэш-значение для этого Bucket. Любое количество объектов может иметь один и тот же хэш-код, в зависимости от алгоритма, используемого для вычисления хэш-кодов.
Идеальный алгоритм - это тот, который генерирует разные хэш-коды для разных объектов. Итак, в идеале 1 object
за bucket
. Конечно, это идеальный случай, который может быть невозможен.
Ведро может, конечно, содержать несколько объектов, основанных на некотором свойстве.
Ответ 3
Подумайте о hashcode как о чем-то, что просто уменьшает усилия при проверке равенства.
Если два объекта равны, у них обязательно будет один и тот же хэш-код. Однако, если два объекта имеют один и тот же хэш-код, они могут иметь математически высокое сходство, но все равно не совпадать. Только для мышления: подумайте о сравнении утки с слоном в зоопарке. Они очень разнородны и будут иметь различный абстрактный хэш-код, поэтому вам не нужно будет сравнивать их ноги, крылья и т.д., Чтобы проверить, одинаковы ли они. Однако, если вы сравниваете утку и лебедя, они очень похожи и имеют один и тот же абстрактный хэш-код, поэтому теперь вы сравниваете очень мелкие черты каждого животного, чтобы проверить равенство. Когда вы уменьшаете экстренность между двумя сравниваемыми элементами, абстрактный хэш-код становится все более конкретным. Как и сравнение уток и лебедей имеет более конкретный хэш-код, чем сравнение уток и слонов, сравнение разных пород уток делает хеш-код еще более конкретным, сравнивая dna двух уток той же породы, делает хэш-код еще более конкретным. Этот ответ предназначен только для создания мышления, чтобы понять концепцию хэш-кода. Прочитав это, вы должны размыть понимание слова hashcode в контексте этого ответа.
Ответ 4
Я думаю, что наоборот -
если два объекта НЕ равны в соответствии с методом equals(), они должны имеют значение A DIFFERENT hashCode()
который явно не выполняется, поскольку генерация уникальных хэшей в общем случае невозможна, потому что вы обычно пытаетесь сопоставить набор значений с набором хеш-кодов меньшей мощности.
Ответ 5
Я объясню это с помощью примера. Скажем, что строка hashCode()
строки основана на длине строки. В этом случае хэш-код "foo"
и "bar"
равен. Но сам "foo"
не равен "bar"
.
Это потому, что код реализует своего рода формулу: вы можете определить код для каждого объекта, но не можете восстановить объект из хэш-кода. Может быть несколько объектов с одинаковым хеш-кодом.
Ответ 6
Вы можете определить реализацию hashCode()
, чтобы всегда возвращать пример 1
. Это совершенно справедливо: разные экземпляры (которые не являются equal
) могут иметь один и тот же hashCode
. Но производительность выполнения этих объектов в HashMaps
, Sets
или других типах коллекций будет очень плохой (поскольку все они попадают в один и тот же ковш внутри - производительность поиска ухудшается от O(1)
до O(n)
, потому что вам нужно пройти список объектов в одном ковше).
Также рассмотрим возможность взглянуть на как работает HashMaps в Java.
Ответ 7
Хэш-код объекта обычно намного меньше исходного объекта. Это одна из целей хэш-функции. Таким образом, вы можете себе представить, что если у вас есть n разных объектов (скажем, все перестановки класса), их невозможно закодировать в m (где m < n) разные и меньшие (чем исходный объект) уникальные коды.
Ответ 8
Позвольте мне показать пример:
предположим, что HashCode строки получается следующим образом: hashCode = сумма каждого символьного кода ASCII (но мы знаем, что реальный хэш сложнее)
Например: хеш-код "abc" вычисляет в такой форме: 49 + 50 + 51 = 150
Тогда хеш-код "acb" равен: 49 + 51 + 50 = 150
И так далее. как вы можете видеть, существует много строк с hashcode = 150, но они не равны.