Два экземпляра, имеющие один и тот же хэш-код, но не равный

Я читал приведенный ниже параграф из статьи под названием Теория и практика 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, но они не равны.