Оператор ==
является ложным другом в Java. Он работает должным образом только на примитиве и заставит вас плакать, если вы использовали его на любом другом объекте , на который ссылаются
, по большей части.
Основной
Как правило, каждый метод равен
должен начинаться так:
@Override public boolean equals(Object obj) { if (obj == null) { return false; } if (!(obj instance ClassName)) { return false; } // custom logic here }
Имя класса должно быть заменено любым типом вашего класса. После этого я обычно применяю одно из следующих решений.
Класс как только одно релевантное поле
В случае, если в классе есть только одно соответствующее поле, я автоматически верну либо операцию ==
(для примитива), либо равно
поля.
public class Person private String fullname; @Override public boolean equals(Object obj) { if (obj == null) { return false; } if (!(obj instance Person)) { return false; } Person converted = (Person)obj; return this.fullname.equals(converted.fullname); } }
Класс, как можно больше соответствующих полей
Обычно у меня здесь есть два варианта.
Функция toString() содержит все соответствующие поля
Нет необходимости усложнять класс, если что-то может помочь вам с вашим кодом. Нет необходимости проверять наличие экземпляра
, так как toString
определяется везде, и нет необходимости приводить по той же причине.
public class Person private String firstname; private String lastname; @Override public String toString() { return this.firstname + " " + this.lastname; } @Override public boolean equals(Object obj) { if (obj == null) { return false; } return this.toString().equals(obj.toString()); } }
Это не обязательно должно быть toString
. Иногда другие методы выполняют ту же работу. Вы должны иметь в виду, что другие методы потребуют проверки и приведения объекта перед сравнением.
Нет никакого способа помочь
В такой ситуации я обычно буду каскадировать if
до последнего соответствующего поля.
public class Person private String firstname; private String lastname; private Date dob; @Override public boolean equals(Object obj) { if (obj == null) { return false; } if (!(obj instance Person)) { return false; } Person converted = (Person)obj; if (!(this.firstname.equals(converted.firstname)) { return false; } if (!(this.lastname.equals(converted.lastname)) { return false; } return this.dob.equals(converted.dob); } }
Я знаю, что, вероятно, мог бы сделать что-то подобное:
return this.firstname.equals(converted.firstname) && this.lastname.equals(converted.lastname) && this.dob.equals(converted.dob);
Мне это не очень нравится, потому что в основном это трудно читать. Я знаю, что Java, вероятно, оптимизирует байт-код с помощью такого рода инструкций, тем не менее, я считаю, что в большинстве случаев это не будет иметь большого значения.
Не забывайте, что для того, чтобы иметь возможность использовать HashMap
и прочее, вам также необходимо переопределить хэш-код
. Вот основные правила:
- Если 2 экземпляра равны, то оба
хэш-кода
ДОЛЖНЫ БЫТЬ равны; - Если 2 экземпляра не равны, то оба
хэш-кода
НЕ ДОЛЖНЫ БЫТЬ равны.
Хороший хэш-код
алгоритм, соответствующий второму правилу, будет использовать Хэш-карту
и Набор хэшей
более эффективен.
Оригинал: “https://dev.to/havarem/override-equals-method-in-java-2b3j”