Мой сотрудник переопределял метод equals()
. Мой ответ был, вы также переопределили метод hashCode()
? Его ответ заключался в том, что мы не будем использовать хэш-карту или хеш-набор, не имеет значения, переопределяем ли мы hashCode()
. Это правильно?
Переопределение метода hashCode() не требуется, если мы не используем hashmap или hashset
Ответ 1
Да, он фактически прав - однако, если вам нужно положить ваши объекты в коллекцию на основе хэшей в один прекрасный день, вам придется добавлять хэш-коды повсюду, что может раздражать + в этот день вы можете неправильно реализовать свой хэш-код ( т.е. не согласуется с равными), потому что вы пропускаете некоторую тонкость в методе equals...
Учитывая, что большинство IDE предоставляют функцию генерации автоматически равных/хэш-кодов, я вижу мало причин не создавать их.
Еще один способ взглянуть на это: когда вы переопределяете метод из родительского класса, вы должны следовать контракту, определенному этим родительским классом. В случае Object, javadoc равных довольно ясно:
Обратите внимание, что обычно необходимо переопределить метод hashCode всякий раз, когда этот метод переопределяется, чтобы поддерживать общий контракт для метода hashCode, который утверждает, что равные объекты должны иметь одинаковые хэш-коды.
Поэтому, если у вас нет реальной причины разработки, чтобы не переопределять hashcode, решение по умолчанию должно заключаться в том, чтобы следовать контракту родительского класса и не применять ни к одному, ни к обоим.
Ответ 2
Если вы переопределите equals()
, переопределите hashCode()
. Даже если вы не используете hashCode()
сейчас, вы или кто-то другой можете его использовать.
Подробнее об этой теме, проверьте отличный ответ SO >
Ответ 3
Это запах кода. Например, Findbugs предупредит вас, если вы переопределите либо hashCode, либо равны без переопределения другого. Вы должны переопределить оба параметра так, чтобы они соответствовали друг другу (то есть a.equals(b) = > a.hashCode() == b.hashCode()).
Теперь небольшое усилие может сэкономить много головных болей.
Ответ 4
Вы должны переопределить hashCode в каждом классе, который переопределяет равные. Несоблюдение этого требования приведет к нарушению общего контракта для Object.hashCode, который предотвратит правильное функционирование вашего класса в сочетании со всеми коллекциями на основе хэшей, включая HashMap, HashSet и Hashtable.
Эффективный Java Item 9: Всегда переопределять hashCode при переопределении равных.
Если ваш класс является открытым классом, вы не можете контролировать, как ваши классы будут использоваться в будущем развитии. Не глядя в исходный код (или через отражение), нет способа узнать, переопределил ли этот класс метод hasCode или нет, и пользователь будет удивлен результатом, если он будет использовать его в любых хэш-наборах.
Ответ 5
Общие:
только переопределять те методы, которые вы хотите использовать по-своему, а также те методы, которые подвержены этому переопределению.
Конкретно для ваших вопросов:
Из java docs,
Обратите внимание, что обычно необходимо переопределить метод hashCode когда метод equals() переопределяется, чтобы поддерживать общий контракт для метода hashCode, который утверждает, что равные объекты должны имеют одинаковые хэш-коды.
Ответ 6
На самом деле предположим, что вы создаете два разных объекта без переопределения методов equals и hashCode. И тогда, если вы вызываете метод equals, java вызывает метод hashCode неявно, то проверяет равенство хэш-кодов.
Переопределить метод hashCode достаточно для проверки равенства двух объектов. И это будет полезно для будущего. Вы можете использовать этот класс в коллекциях.
В противном случае, если вы реализуете только равный метод, он будет решать только равенство двух объектов не более.