Почему нам нужно переопределить метод equals() в Java?

У меня есть путаница в причине того, что мы переопределяем метод .equals.

Например:

Test test1 = new Test(3);
Test test2 = new Test(3);

//The if comparison does the same thing that the overridden '.equals()' method does.
if(test1.equals(test2)){
    System.out.println("test1 and test2 are true in .equals()");
}

// Override .equals method.
public boolean equals(Object object) {
    if(object instanceof Test && ((Test)object).getValue() == this.t) {
        return true;
    } else {
        return false;
    }
}

Я не понимаю, почему мы должны переопределить метод .equals().

Ответ 1

Из статьи Переопределить equals и hashCode в Java:

Реализация по умолчанию класса equals(), предоставленного java.lang.Object сравнивает местоположение памяти и только возвращает true, если две ссылочные переменные указывают на одно и то же место памяти, то есть по существу они - один и тот же объект.

Java рекомендует переопределять equals и метод hashCode, если равенство будет определено логическим путем или через некоторую бизнес-логику: example:

многие классы в стандартной библиотеке Java переопределяют его, например. String переопределяет equals, реализация которого equals() возвращает true, если содержимое двух объектов String точно такое же

Обозначения класса оболочки Integer равны для выполнения численного сравнения и т.д.

Ответ 2

Этого должно быть достаточно, чтобы ответить на ваш вопрос: http://docs.oracle.com/javase/tutorial/java/IandI/objectclass.html

Метод equals() сравнивает два объекта для равенства и возвращает true, если они равны. Метод equals(), предоставляемый в классе Object, использует оператор идентификации (==), чтобы определить, равны ли два объекта. Для примитивных типов данных это дает правильный результат. Однако для объектов это не так. Метод equals(), предоставляемый Object, проверяет, являются ли ссылки на объекты равными, то есть, если сопоставленные объекты являются точным одним и тем же объектом.

Чтобы проверить, равны ли два объекта в смысле эквивалентности (содержащие одну и ту же информацию), вы должны переопределить метод equals().

(Частичная цитата - нажмите, чтобы прочитать примеры.)

Ответ 3

.equals() не выполняет интеллектуальное сравнение для большинства классов, если класс не переопределяет его. Если он не определен для (пользовательского) класса, он ведет себя так же, как ==.

Ссылка: http://www.leepoint.net/notes-java/data/expressions/22compareobjects.html http://www.leepoint.net/data/expressions/22compareobjects.html

Ответ 4

Поведение по умолчанию для java.lang.Object - сравнение ссылок, но это не подходит для каждого типа объектов. Есть вещи, называемые Объекты значения (например, BigDecimal или String), где объекты с одинаковым значением считаются взаимозаменяемыми, поэтому поведение по умолчанию равно нежелательно. Эти объекты должны реализовать equals и hashcode на основе значения, которое объект принимает.

Ответ 5

Чтобы ответить на ваш вопрос, во-первых, я настоятельно рекомендую посмотреть Документация.

Без переопределения метода equals() он будет действовать как "==". Когда вы используете оператор "==" для объектов, он просто проверяет, ссылаются ли эти указатели на один и тот же объект. Нет, если их члены содержат одно и то же значение.

Мы переопределяем, чтобы наш код был чистым и абстрагировал логику сравнения из оператора If в объект. Это считается хорошей практикой и использует преимущества Java объектно-ориентированного подхода.

Ответ 6

Позвольте мне привести вам пример, который мне очень полезен.

Вы можете считать ссылку ссылкой на номер страницы книги. Предположим, теперь у вас есть две страницы a и b, как показано ниже.

BookPage a = getSecondPage();

BookPage b = getThirdPage();

В этом случае a == b даст вам значение false. Но почему? Причина в том, что то, что делает ==, похоже на сравнение номера страницы. Таким образом, даже если контент на этих двух страницах точно такой же, вы все равно получите false.

Но что нам делать, если вы хотите сравнить контент?

Ответ заключается в том, чтобы написать собственный метод equals и указать, что вы действительно хотите сравнить.

Ответ 7

По умолчанию .equals() использует == идентификационную функцию для сравнения, которая явно не работает, поскольку экземпляры test1 и test2 не совпадают. == работает только с примитивными типами данных, такими как int или string. Поэтому вам нужно переопределить его, чтобы он работал, сравнивая все переменные-члены класса Test

Ответ 8

Метод Object.equals() проверяет только ссылку на объект не примитивный тип данных или значение Object (объект класса Wrapper примитивных данных, простой примитивный тип данных (байт, короткий, int, long и т.д.)). Таким образом, мы должны переопределить метод equals(), когда мы сравниваем объект на основе примитивного типа данных.