Коллекции Java – hashCode() и equals() – Как переопределить методы equals() и hashcode() в Java?

Опубликовано: 2018-08-08
Хэш-код коллекций Java и эквиваленты

equals() и hashCode() в Java — это два фундаментальных метода, которые объявлены в классе Object и частично или в основной библиотеке Java.

Если у вас есть какие-либо из перечисленных ниже проблем в Java, то вы попали по адресу.

  • Практика Java -> Реализация равных
  • override — переопределение equals и hashCode в Java
  • Как переопределить метод equals() в java
  • Как переопределить метод hashCode() в java
  • Как переопределить метод equals и hashCode в Java
  • Как и зачем переопределять метод equals в Java
  • Зачем всегда переопределять hashcode(), если переопределяется equals()?

Давайте рассмотрим простой пример, чтобы понять первое Reference Equality и Logical Equality . Оператор равенства (==) сравнивает ссылки (адреса в памяти) двух строк как два разных числа — это известно как Reference equality .

Logical equality сравнивает данные объектов вместо значения ссылок.

Выход:

hashCode и equals тесно связаны:

  • если вы переопределяете equals , вы должны переопределять hashCode .
  • hashCode должен генерировать одинаковые значения для одинаковых объектов.
  • equals и hashCode должны зависеть от одного и того same set of significant fields . Вы должны использовать один и тот же набор полей в обоих этих методах. Вы не обязаны использовать все поля. Например, вычисляемое поле, которое зависит от других, скорее всего, должно быть исключено из equals и hashCode .

При реализации equals поля сравниваются по-разному, в зависимости от их типа:

  • поля объекта, включая коллекции: используйте equals
  • Типобезопасные перечисления: используйте либо equals , либо == (в данном случае это одно и то же)
  • поля объектов с возможными нулевыми значениями: используйте как == , так и equals
  • поля массива: используйте Arrays.equals
  • примитивные поля, отличные от float или double : используйте ==
  • float : преобразовать в int , используя Float.floatToIntBits , затем используйте ==
  • double : преобразовать в long с помощью Double.doubleToLongBits , затем использовать ==

Реализация хэш-кода :

  • если класс переопределяет equals , он должен переопределять hashCode
  • когда они оба переопределены, equals и hashCode должны использовать один и тот же набор полей
  • если два объекта равны, то их значения hashCode также должны быть равны
  • если объект неизменяем, то hashCode является кандидатом на кеширование и ленивую инициализацию

Это популярное заблуждение, что hashCode предоставляет уникальный идентификатор для объекта. Это не.

Согласно общему соглашению, метод equals() в Java должен быть рефлексивным, симметричным, транзитивным, непротиворечивым, и любая ненулевая ссылка должна возвращать false. Другими словами, для произвольных значений a, b и c всегда должны проходить следующие тесты:

Для лучшей практики используйте следующие шаги для реализации вашего метода equals():

  • Используйте это == это, чтобы проверить ссылочное равенство
  • Используйте instanceof для проверки правильности типа аргумента
  • Приведите аргумент к правильному типу
  • Сравните значимые поля на равенство

Вот полный пример.

CrunchifyImplementEqualsHashCode.java

Вывод консоли Eclipse: