Что такое метод equals

Ответ

Метод equals() используется для сравнения объектов на содержательное равенство (по значению полей), в отличие от оператора ==, который сравнивает ссылки (адреса в памяти).

@Override
public boolean equals(Object obj) {
    if (this == obj) return true;
    if (obj == null || getClass() != obj.getClass()) return false;
    MyClass other = (MyClass) obj;
    return field1 == other.field1 && Objects.equals(field2, other.field2);
}

Обязательные требования:

  • Рефлексивность: x.equals(x) == true
  • Симметричность: x.equals(y) == y.equals(x)
  • Транзитивность: если x.equals(y) и y.equals(z), то x.equals(z)
  • Консистентность: повторные вызовы дают одинаковый результат
  • Неравенство с null: x.equals(null) == false

Всегда переопределяйте hashCode(), если переопределяете equals(), чтобы соблюдать контракт hashCode-equals.

Ответ 18+ 🔞

А, ну вот, опять про этот equals заговорили. Ёпта, сколько можно-то? Ладно, слушай сюда, раз уж начал.

Представь себе, что у тебя два паспорта на одного человека. По факту — один и тот же чувак, но бумажки-то разные, да? Оператор == — это как взять и сравнить сами бланки паспортов: одинаковые ли они? Нет, конечно, блядь, разные же бумажки! А вот метод equals() — это уже умное сравнение: а ну-ка, проверим ФИО, дату рождения, номер — о, да это же один и тот же человек! Вот и вся разница, ебать мои старые костыли. == смотрит на ссылки (эти ебучки адреса в памяти), а equals() — на содержание, на то, что внутри объекта.

Вот, глянь, как это обычно выглядит в коде, когда его пишет не ленивая жопа:

@Override
public boolean equals(Object obj) {
    if (this == obj) return true; // А, так это я и есть? Ну ок, тру
    if (obj == null || getClass() != obj.getClass()) return false; // Ты кто такой, сука? Иди нахуй
    MyClass other = (MyClass) obj; // Ладно, раз уж ты из нашей банды, давай кастовать
    return field1 == other.field1 && Objects.equals(field2, other.field2); // Теперь сравниваем по полям, как взрослые
}

Но тут, чувак, не всё так просто, ёклмн. Чтобы твой метод не был пиздопроебибным и не сломал пол-системы, есть жёсткие правила, контракт, блядь. Нарушишь — получишь хитрая жопа в виде неработающих коллекций.

Вот эти самые правила, их надо выжечь на подкорке:

  • Рефлексивность: Объект должен быть равен самому себе. x.equals(x) — всегда true. Если это не так, то ты, прости, совсем ебанько.
  • Симметричность: Если x равен y, то и y должен быть равен x. Не может быть такого, что ты меня признал, а я тебя — нет, пидарас шерстяной.
  • Транзитивность: Если x равен y, а y равен z, то и x обязан быть равен z. Цепочка, блядь, логическая.
  • Консистентность: Сколько ни вызывай equals() на неизменённых объектах — результат должен быть один и тот же. Не может он сегодня сказать true, а завтра — false, это же не прогноз погоды.
  • Неравенство с null: Любой объект, даже самый ебаный, при сравнении с null должен возвращать false. Это святое.

И вот теперь главное, блядь, запомни раз и навсегда, а то потом будешь орать "почему не работает?!" — если переопределил equals(), В ОБЯЗАТЕЛЬНОМ ПОРЯДКЕ переопредели и hashCode(). Это как сиамские близнецы, ёпта. Не сделаешь — HashMap, HashSet и прочая братва просто перестанут тебя узнавать, будут считать разными объектами, даже если по твоему equals() они одинаковые. Доверия ебать ноль у них к таким, как ты. Контракт, детка, его надо соблюдать, иначе всё накрывается медным тазом.