Почему мы должны переопределить метод 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() метод.

8 ответов

Из статьи Override equals и hashCode в Java:

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

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

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

Целочисленный класс-оболочка переопределяет значение для выполнения числового сравнения и т. Д.

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

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

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

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

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

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

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

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

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

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

BookPage a = getSecondPage ();

BookPage b = getThirdPage ();

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

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

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

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

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

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

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

Другие вопросы по тегам