Object, Equals и HashCode Flashcards
класс Object
Все классы являются наследниками суперкласса Object.
Объект Object может ссылаться на объект любого другого класса.
методы класса Object
- Class getClass() — возвращает в рантайме класс данного объекта.
- int hashCode() — возвращает хеш-код
- boolean equals(Object obj) — сравнивает объекты.
- Object clone() - клонирование объекта
- String toString() — возвращает строковое представление объекта.
- void notify() — просыпается один поток, который ждет на “мониторе” данного объекта.
- void notifyAll() — просыпаются все потоки, которые ждут на “мониторе” данного объекта.
- void wait(long timeout) - поток переходит в режим ожидания в течение указанного времени.
- void wait() - приводит данный поток в ожидание, пока другой поток не вызовет notify() или notifyAll() методы для этого объекта.
- void wait(long timeout, int nanos) - приводит данный поток в ожидание, пока другой поток не вызовет notify() или notifyAll() для этого метода, или пока не истечет указанный промежуток времени.
- void finalize() - вызывается сборщиком мусора, когда garbage collector определил, что ссылок на объект больше нет.
метод equals()
это метод класса Object, который используется для сравнения объектов на предмет логического равенства
метод hashCode()
Это метод класса Object, который возвращает целочисленное значение (хэш-код) объекта.
Хэш-код используется в таких структурах данных, как HashMap, HashSet и HashTable для более быстрого поиска объектов.
Как работает метод equals() по умолчанию?
По умолчанию метод equals() в классе Object сравнивает ссылки (адреса в памяти) объектов. Если объекты указывают на один и тот же адрес в памяти, возвращается true, иначе — false.
Как работает метод hashCode() по умолчанию?
Метод hashCode() по умолчанию возвращает уникальное целочисленное значение, основанное на внутреннем представлении адреса объекта в памяти.
Зачем переопределять метод equals()?
Метод equals() переопределяют, чтобы сравнивать объекты по логическому содержимому (состоянию), а не по их адресам в памяти. Это полезно, когда нужно определить эквивалентность объектов на основе их полей.
Зачем переопределять метод hashCode()?
Переопределение hashCode() необходимо, если вы переопределили equals().
Это делается для того, чтобы объекты, которые считаются равными по методу equals(), имели одинаковый хэш-код, иначе структуры данных на основе хэширования будут работать неправильно.
Какие контракты должны выполняться при переопределении equals() и hashCode()?
- Рефлексивность: объект должен быть равен самому себе.
- Симметричность: если a.equals(b) возвращает true, то и b.equals(a) должно вернуть true.
- Транзитивность: если a.equals(b) и b.equals(c), то a.equals(c) должно также вернуть true.
- Непротиворечивость: если объекты не изменяются, многократные вызовы equals() должны возвращать одинаковое значение.
- Связь с hashCode(): если два объекта равны согласно equals(), то их хэш-коды также должны быть равны.
Что произойдет, если переопределить equals(), но не переопределить hashCode()?
Если переопределить только equals(), но не переопределить hashCode(), то объекты, которые равны по equals(), могут иметь разные хэш-коды.
Это нарушит контракт между equals() и hashCode(), что приведет к ошибкам при работе с хэш-таблицами (например, HashMap, HashSet).
Как правильно переопределить hashCode()?
Метод hashCode() должен быть согласован с equals().
Для этого обычно используют все поля объекта, участвующие в сравнении в методе equals().
Это можно сделать с помощью умножения хэш-кодов полей на простые числа для уменьшения коллизий.
Что такое “коллизия хэш-кодов”?
Коллизия хэш-кодов возникает, когда два различных объекта имеют одинаковый хэш-код. Это неизбежно в хэш-структурах данных, и их нужно минимизировать, но не полностью исключить.
Почему важно минимизировать коллизии хэш-кодов?
Частые коллизии могут снижать производительность хэш-структур, так как они приводят к тому, что несколько объектов помещаются в одну корзину (bucket), и тогда они должны быть дополнительно проверены с помощью метода equals().
Что такое консистентность между equals() и hashCode()?
Консистентность между этими методами означает, что если два объекта равны по equals(), то их хэш-коды тоже должны быть равны.
Это важно для корректной работы объектов в хэш-структурах данных.
Что произойдет, если два объекта имеют одинаковый хэш-код, но не равны по equals()?
Такая ситуация допустима. Однако при вставке в хэш-структуру может произойти коллизия, и тогда будет использован метод equals() для точной проверки на равенство.