Различные поля для равных и хэш-кода

Я согласен с утверждением из этого поста. Какие проблемы следует учитывать при переопределении equals и hashCode в Java?

Используйте тот же набор полей, который вы используете для вычисления equals() для вычисления hashCode().

Но у меня есть некоторые сомнения:

  • Это обязательно необходимо иметь одинаковые поля?
  • Если да, что если я не использую то же поле?
  • Повлияет ли это на производительность HashMap или точность HashMap?

2 ответа

Поля не должны быть одинаковыми. Требование к двум равным объектам, они должны иметь одинаковый хэш-код. Если у них одинаковый хэш-код, они не обязательно должны быть равны. Из Javadocs:

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

Например, вы можете всегда возвращать 1 в качестве хеш-кода и подчиняться контракту хеш-кода, независимо от того, какие поля вы использовали в своем методе equals.

Постоянный возврат 1 увеличит время вычисления hashCode, но производительность HashMap упадет, так как ему придется чаще прибегать к equals().

Это обязательно необходимо иметь одинаковые поля?

Да, если вы не хотите никаких сюрпризов.

Если да, что если я не использую то же поле?

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

Например, предположим, у вас есть 3 поля - a, b, c, А вы используете a а также b за equals() метод, и все 3 поля для hashCode() метод. Итак, для 2 объектов, если a а также b равны, и c отличается, оба будут равны с другим хэш-кодом.

Повлияет ли это на производительность HashMap или точность HashMap?

Дело не в производительности, но да, ваша карта будет вести себя не так, как ожидалось.

Поля, используемые в хеш-коде, могут быть подмножеством полей, используемых в равных. Он по-прежнему будет придерживаться этого правила: "Всякий раз, когда a.equals(b), a.hashCode() должен совпадать с b.hashCode()"

Другие вопросы по тегам