Ответ
Метод equals() переопределяют, чтобы сравнивать объекты по их внутреннему состоянию (значениям полей), а не по ссылке, как это делает реализация по умолчанию из класса Object.
Пример:
public class Person {
private String name;
private int age;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return age == person.age && Objects.equals(name, person.name);
}
}
Почему это важно:
- Коллекции: Без корректного
equals()коллекции вродеArrayList.contains()илиHashSetбудут работать неправильно. - Контракт с hashCode(): При переопределении
equals()обязательно нужно переопределитьhashCode(), чтобы объекты, которые равны поequals(), имели одинаковый хэш-код. Это требование для корректной работыHashMapиHashSet. - Принципы: Реализация должна быть рефлексивной, симметричной, транзитивной и консистентной. Используйте
Objects.equals()для безопасного сравнения полей, которые могут бытьnull.
Ответ 18+ 🔞
А, ну вот, опять про этот ваш equals(), классика жанра, блядь! Сидит такой джавист, думает: «О, у меня два человека, оба Васей зовут, оба по тридцать лет — ну это же один и тот же мужик, ёпта!». А Java ему такая: «Хуй там, сынок, это две разные ссылки в памяти, нихуя не равны». И пошёл наш страдалец equals() переопределять, чтобы логику человеческую, а не машинную, впилить.
Смотри, вот тебе живой пример, чтоб не быть мудаком:
public class Person {
private String name;
private int age;
@Override
public boolean equals(Object o) {
if (this == o) return true; // если это один и тот же объект — сразу true, нехуй мозги парить
if (o == null || getClass() != o.getClass()) return false; // если null или вообще не Person — false, иди нахуй
Person person = (Person) o; // приводим тип, теперь можно поля сравнивать
return age == person.age && Objects.equals(name, person.name); // вот она, магия, сравниваем по смыслу!
}
}
А нахуя это всё, спросишь? Да затем, что без этого — пиздец, а не жизнь!
- Коллекции, сука! Возьмёшь
HashSet, положишь туда Васю. Потом создашь другого Васю, с теми же полями, и спросишь: «А есть у меня тут Вася?». АHashSetтебе, с видом идиота: «Нету, блядь, я по ссылкам смотрю, а это новая ссылка». И сидишь ты, обосранный, с пустым результатом. А с правильнымequals()— всё работает, как часы, находит твоего Васю по содержимому. - Контракт с
hashCode()— это святое, ёбана! Это как близнецы-братья: переопределилequals()— обязательно переопределяй иhashCode(). ИначеHashMapиHashSetпросто сойдут с ума и начнут терять твои объекты в своих недрах. Правило железное: если два объекта равны поequals(), их хэш-коды должны совпадать. Иначе — welcome to адская отладка. - Принципы, блядь, не выдумывай! Реализация должна быть предсказуемой: рефлексивной (объект равен сам себе), симметричной (если А равен Б, то и Б равен А), транзитивной и консистентной (сколько ни сравнивай — результат один). И главный лайфхак — используй
Objects.equals()для сравнения строк и прочего, что может бытьnull, чтобы не получитьNullPointerExceptionв самый неподходящий момент, как оплеуху.
Вот и вся магия, не такой уж он и страшный, этот equals(). Главное — делай с умом и не забудь про его кореша hashCode(), а то будет тебе, как Герасиму с Муму — вроде и хотел как лучше, а получил сплошную трагедию и совесть, которая жрёт изнутри.