July 19, 2018

Особенности equals и hashCode

В java hashCode - целочисленное представление объекта. Метод hashCode класса Object возвращает значение типа int. Этот метод имеет модификатор native, т.е. он написан не на java. (Как вычисляется hashCode)

Особенности hashCode:

  • для одного и того-же объекта, хеш-код всегда будет одинаковым;
  • если объекты равны, то и хеш-коды одинаковые (но не наоборот, см. правило 3).
  • если хеш-коды равны, то входные объекты не всегда равны (коллизия);
  • если хеш-коды разные, то и объекты гарантированно разные;

Равенство объектов проверяется методом equals класса Object.

Для корректной работы этого метода в ваших классах его нужно переопределять, т.к. в классе Object он определен так:

public boolean equals(Object obj) {
        return (this == obj);
}

Т.е. в классе Object метод equals проверяет объекты только на равенство по ссылке.

Существуют ограничения на переопределение equals. Метод должен обладать следующими свойствами:

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

Псевдокод для переопределения equals:

  • сравнить ссылки на объекты. Если они равны, вернуть true
  • сравнить тип передаваемого объекта с типом нашего объекта. Если объект другого типа - вернуть false.
  • Привести сравниваемый объект к типу нашего объекта
  • Сравнить значимые поля объектов

Источники