Различные поля для равных и хэш-кода
Я согласен с утверждением из этого поста. Какие проблемы следует учитывать при переопределении 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()"