Найти в Дзене
JavAKnazzz

Java. Equals и Hashcode

Хеш-код — это целочисленный результат работы метода, которому в качестве входного параметра передан объект.
Если более точно, то это битовая строка фиксированной длины, полученная из массива произвольной длины. Когда у разных объектов одинаковые хеш-коды называется — коллизией.
Equals - это метод, определенный в Object, который служит для сравнения объектов. При сравнении объектов при помощи == идет сравнение по ссылкам. При сравнении по equals() идет сравнение по состояниям объектов.
Свойства equals():
• Симметричность: Для двух ссылок, a и b, a.equals(b) тогда и только тогда, когда b.equals(a)
• Рефлексивность: для любого заданного значения x, выражение x.equals(x)
должно возвращать true.
Заданного — имеется в виду такого, что x != null
• Постоянство: повторный вызов метода equals() должен возвращать одно и тоже значение до тех пор, пока какое-либо значение свойств объекта не будет изменено.
• Транзитивность: Если a.equals(b) и b.equals(c), то тогда a.equals(c)
• Совместимость с h

Хеш-код — это целочисленный результат работы метода, которому в качестве входного параметра передан объект.
Если более точно, то это битовая строка фиксированной длины, полученная из массива произвольной длины.

Когда у разных объектов одинаковые хеш-коды называется — коллизией.



Equals
- это метод, определенный в Object, который служит для сравнения объектов. При сравнении объектов при помощи == идет сравнение по ссылкам. При сравнении по equals() идет сравнение по состояниям объектов.

Свойства equals():
Симметричность: Для двух ссылок, a и b, a.equals(b) тогда и только тогда, когда b.equals(a)
Рефлексивность: для любого заданного значения x, выражение x.equals(x)
должно возвращать true.
Заданного — имеется в виду такого, что x != null

Постоянство: повторный вызов метода equals() должен возвращать одно и тоже значение до тех пор, пока какое-либо значение свойств объекта не будет изменено.
Транзитивность: Если a.equals(b) и b.equals(c), то тогда a.equals(c)
Совместимость с hashCode(): Два тождественно равных объекта должны иметь одно и то же значение hashCode()


При переопределении equals() обязательно нужно переопределить метод hashCode(). Равные объекты должны возвращать одинаковые хэш коды.

Каким образом реализованы методы hashCode() и equals() в классе Object?

Метод hashCode() в классе Object реализован таким образом, что он возвращает уникальный числовой идентификатор объекта. Этот идентификатор вычисляется на основе хеш-функции, которая применяется к содержимому объекта.

Метод equals() в классе Object сравнивает два объекта на равенство. Он сравнивает ссылки на объекты, чтобы проверить, указывают ли они на один и тот же объект. Если ссылки указывают на один и тот же объект, то метод возвращает true. Если ссылки указывают на разные объекты, то метод возвращает false.

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

Какой контракт между hashCode() и equals()?

1) Если два объекта возвращают разные значения hashcode(), то они не могут быть равны
2) Если equals объектов true, то и хэшкоды должны быть равны.
3) Переопределив equals, всегда переопределять и hashcode.

Правила переопределения equals()

1. Проверить на равенство ссылки объектов this и параметра метода o.
if (this == o) return true;
2. Проверить, определена ли ссылка o, т. е. является ли она null.
Если в дальнейшем при сравнении типов объектов будет использоваться оператор instanceof, этот пункт можно пропустить, т. к. этот параметр возвращает false в данном случае null instanceof Object.
3. Сравнить типы объектов this и o с помощью оператора instanceof или метода getClass(), руководствуясь описанием выше и собственным чутьем.
4. Если метод equals переопределяется в подклассе, не забудьте сделать вызов super.equals(o)
5. Выполнить преобразование типа параметра o к требуемому классу.
6. Выполнить сравнение всех значимых полей объектов:
o для примитивных типов (кроме float и double), используя оператор ==
o для ссылочных полей необходимо вызвать их метод equals
o для массивов можно воспользоваться перебором по циклу, либо методом Arrays.equals()
o для типов float и double необходимо использовать методы сравнения соответствующих оберточных классов Float.compare() и Double.compare()

Правила переопределения метода hashcode().

Если хеш-коды разные, то и входные объекты гарантированно разные.
Если хеш-коды равны, то входные объекты не всегда равны.
При вычислении хэш-кода следует использовать те же поля, которые сравниваются в equals и которые не вычисляются на основе других значений.

- вызов метода hashCode один и более раз над одним и тем же объектом должен возвращать одно и то же хэш-значение, при условии что поля объекта, участвующие в вычислении значения, не изменялись.
- вызов метода hashCode над двумя объектами должен всегда возвращать одно и то же число, если эти объекты равны (вызов метода equals для этих объектов возвращает true).
- вызов метода hashCode над двумя неравными между собой объектами должен возвращать разные хэш-значения. Хотя это требование и не является обязательным, следует учитывать, что его выполнение положительно повлияет на производительность работы хэш-таблиц.