Метод equals в Java

Java

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

В своей работе программистам часто приходится проверять равенство объектов. Рассмотрим, как работает сравнение на языке Java.

Сравнение с помощью == и equals в Java

Пример кода:

String s1 = new String(«vscode.ru»);
String s2 = new String(«vscode.ru»);

System.out.println(s1 == s2); //каким здесь будет результат сравнения?
System.out.println(s1.equals(s2)); //а здесь?

Какая разница между этими записями? Чем отличается оператор сравнения == и метод equals?
На самом деле все легко. При сравнении метод equals проверяет и сопоставляет значения объектов и на основе этого приходит к выводу раны они или нет (true или false).

Оператор == сравнивание значение переменных (в случае с примитивными типами данных) и возвращает результат. Однако в случае со ссылочными типами данных (массивы, объекты и так далее) сравнивает ссылки на объекты в памяти ПК, и на основе анализа выдает результат true или false. Вот и все отличие метода метода equals и оператора == в Java.

Метод equals представляет собой метод класса Object. При этом каждый объект неявно унаследован от класса Object и способен вызывать метод equals. Рассмотрим пример, который мы привели выше. Можно сделать вывод о результате операции сравнения в двух случаях:

  • System.out.println(s1 == s2); //возвращено false. Сравниваются ссылки, а они отличаются.
  • System.out.println(s1.equals(s2)); //возвращено true, так как значения объектов равны (они одинаковые).

Важно! Вместо класса String, может объявляться любой другой ссылочный тип данных (ваш пользовательский класс, ArrayList<>, Object и так далее).

Переопределение метода equals в Java

В каких случаях нужно предопределять метод equals? Это необходимо делать тогда, когда определено понятие логической эквивалентности для вашего класса. При этом эквивалентность не совпадает с тождественностью объектов. К примеру, это понятие можно применять для классов String и Integer.

Переопределение метода equals требуется не только, чтобы удовлетворить ожидания программистов. С его помощью можно использовать экзепляры класса как ключи в определенной схеме или элементов в некотором наборе с необходимым и предсказуемым поведением. Что это означает?

Приведем пример кода:

public class Address {
private Integer number;
private String street;

public Address(Integer number, String street) {
this.number = number;
this.street = street;
}

public Integer getNumber() {
return number;
}

public String getStreet() {
return street;
}

public static void main(String[] args) {
List<Address> addressList = new ArrayList<>();
addressList.add(new Address(1, «Test street»));
addressList.add(new Address(1, «Test street»));
while (addressList.remove(new Address(1, «Test street»)));
System.out.println(addressList.size());
}
}

В примере мы создаем список объектов Address, куда добавляем объект класса Address с идентичным конструктором. Данный объект добавляем два раза в List, и с помощью цикла избавляемся от него. Дальше выводим длину списка в консоль.

В результате в консоли, после выполнения программы, отобразится число 2. Возникает вопрос: «Почему кол-во записей в списке осталось неизменным? Ведь наша задача — их удалить». В рассматриваемом примере объекты с одинаковыми полями number и street, но они не удалились.

Во время удаления объектов из списка неявно вызывается метод equals и если объект, передаваемый для удаления, есть в списке, то он удаляется. Использование метода equals в классе Object подразумевает проверку только равенства ссылок. У экзампляторов разные ссылки, так как это различные объекты, каждый из них был разработан с помощью оператора new. Как решить эту проблему?

Ответ очевиден – нужно предопределить метод equals в классе Address:

@Override
public boolean equals(Object o) {
if (this == o) return true;

if (o == null || getClass() != o.getClass()) return false;

Address address = (Address) o;

if (number != null ? !number.equals(address.number) : address.number != null)
return false;

if (street != null ? !street.equals(address.street) : address.street != null)
return false;

return true;
}

После выполнения программы вы увидите, что кол-во объектов в списке теперь равно нулю.

Правила переопределения метода equals в Java

Существует пять правил переопределения метода equals в Java:

  1. Симметричность: для всех нулевых объектов х и у выражение x.equals(y) значение true должно возвращаться только тогда, когда у equals(x) возвратит true.
  2. Рефлексивность: для каждого ненулевого объекта х выражение x.equals(x) должно возвращать логическое значение true.
  3. Транзитивность: для 3-х ненулевых объектов х, у и z, если х.equals(y) возвращает логическое true и у.equals(z) возвращает true, то и выражение х.equals(z) должно возвращать true.
  4. Непротиворечивость: если несколько раз вызвать х.equals(у) для всех ненулевых объектов, то всегда должно возвращаться значение false или true, за исключением того, если никакая информация в объектах не сменилась.
  5. Для всех ненулевых х выражение х.equals(null) должно возвращать логическое значение false.

Для тех, кто не силен в математике, все это выглядит довольно странно. Но попробуйте разобраться в этом, внимательно перечитав все несколько раз. На самом деле здесь нет ничего сложного. Эти правила нарушать нельзя, иначе приложение будет работать неустойчиво и часто завершаться ошибкой. При этом выяснить источник ошибки данного класса будет непросто.

Оцените статью
Образовательный портал WELCOME4U.RU
Добавить комментарий

Adblock
detector