Метод Equals в классе объекта используется для определения того, будет ли объект равен другим объектам. В классе объекта этот метод определяет, имеют ли два объекта одинаковую ссылку. Если два объекта имеют одинаковую ссылку, они должны быть равны. С этой точки зрения, разумно использовать его в качестве операции по умолчанию. Однако для большинства классов это суждение бессмысленно. Например, совершенно не имеет смысла сравнивать, равны ли два отпечатка в этом смысле. Однако часто необходимо обнаружить равенство состояний двух объектов. Если состояния двух объектов равны, два объекта считаются равными. Следовательно, в целом сравнения должны быть переписаны в пользовательских классах.
Вот несколько предложений для написания идеального метода Equals ():
(1) Явный параметр называется другим, и его необходимо преобразовать в переменную, называемую другой позже
(2) Обнаружение того, относятся ли это и другой, относятся к одному и тому же объекту:
if (this == Другое Объект) вернуть true;
Это утверждение просто оптимизация. На самом деле, это форма, которая часто принимается. Потому что вычисление этого уравнения гораздо дешевле, чем сравнение полей в классе один за другим.
(3) Проверьте, является ли другой объем, нулевым, и если нулевой, верните ложь. Этот тест необходим.
if (ore object == null) вернуть false;
(4) Сравните, принадлежат ли это и другое, принадлежащие к одному классу. Если семантика равных изменений в каждом подклассе, используйте getClass (), чтобы обнаружить его, что принимает себя как целевой класс
if (getClass ()! = Другое obhject.getClass ()) вернуть false;
Если все подклассы имеют одинаковую семантику, используйте экземпляр обнаружения
if (! (Другое экземпляр ClassName)) вернуть false;
(5) преобразовать другие объекты в переменную соответствующего типа:
Classname ore = (classname) doreObject;
(6) Теперь начните сравнивать все домены, которые необходимо сравнить. Используйте ==, чтобы сравнить домен базового типа, и использовать равные для сравнения объектного домена. Вернуть истину, если все поля совпадают, в противном случае вернуть false;
return Field1 == Другое.Field1 && Field2.equals (другие.field2)
Если в подкласке переопределяется equals, вы должны включить вызов Super.equals (другие). Если обнаружение не удается, невозможно быть равным. Если домены в суперклассе равны, сравните домены экземпляра в подклассе.
Для полей типа массива вы можете использовать метод статических массивов, чтобы определить, равны ли соответствующие элементы.
Давайте посмотрим на некоторые примеры сравнения струн:
Строка a = "abc"; Строка b = "ABC"; String C = New String ("ABC"); String d = new String ("ABC"); System.out.println (a == b); // true, потому что строковые константы используются в Java, существует только одна система копирования. // false a и c принадлежат 2 различным объектам System.out.println (a equals (c)); // true Поскольку метод Equals строкового объекта сравнивает значения в объекте, он возвращает true. (Отличается от метода Equals) System.out.println (c == d); // Неверно, хотя значения в объектах одинаковы, они принадлежат 2 разным объектам, поэтому они не являются равными System.out.println (C.Equals (d)); // истинныйПроще говоря, при сравнении констант строки это то же самое, что результат, возвращаемый равными. Если вы хотите сравнить значение объекта строки, используйте равные.
См. Пример использования равных:
Пакет глава 05. EqualStest; Импорт java.util.*; public class ровный {public static void main (string [] args) {сотрудник Alice1 = новый сотрудник ("Алиса Адамс", 75000, 1987, 12, 15); Сотрудник Alice2 = Alice1; // Ссылка на тот же объект сотрудник Alice3 = новый сотрудник ("Алиса Адамс", 75000, 1987, 12, 15); Сотрудник Bob = новый сотрудник ("Боб Брандсон", 50000, 1989, 10, 1); System.out.println ("alice1 == alice2:" + (alice1 == alice2)); System.out.println ("alice1 == alice3:" + (alice1 == alice3)); System.out.println ("alice1.equals (alice3):" + (alice1.equals (alice3))); System.out.println ("alice1.equals (bob):" + (alice1.equals (bob))); System.out.println (bob.tostring ()); }} класс сотрудник {public employee (String n, double s, int yar, int month, int day) {name = n; зарплата = s; Gregoriancalendar Calendar = новый Gregoriancalendar (год, месяц, день); hireday = calendar.gettime (); } public String getName () {return name; } public double getAlary () {return Parlary; } public date gethireday () {return hireday; } public void raisesalary (Double Bypercent) {Double Raise = зарплата * Bypercent / 100; зарплата += поднять; } @Override public boolean equals (Object OtherObject) {// быстрый тест, чтобы увидеть, идентифицированы ли объекты, если (это == Другое Объект) вернуть true; // Должен вернуть False, если явный параметр является null, если (другой object == null) вернуть false; // Если классифицируется, не совпадает, они не могут быть равны, если (getClass ()! = Другое obhject.getClass ()) вернуть false; // Теперь мы знаем, что другой, не нулевой сотрудник, другой = (сотрудник), другой, а другой; // Проверьте, есть ли поля Hava идентифицированные значения возвращаемые name.equals (shrel.name) && заработной платы == Другое.salary && hireday.equals (другие.hireday); } @Override public int hashcode () {return 7 * name.hashcode () + 11 * new Double (зарплата) .hashcode () + 13 * hireday.hashcode (); } @Override public String toString () {return getClass (). GetName () + "[name =" + name + ", parlary =" + зарплата + ", hireday =" + hireday + "]"; } private String name; частная двойная зарплата; частное свидание } Менеджер класса расширяет сотрудник {public Manager (String N, Double S, int Year, int Month, int Day) {Super (N, S, год, месяц, день); Bouns = 0; } @Override public double getAlary () {double baseSalary = super.getSalary (); вернуть базовые базы + bouns; } public void setbouns (двойной b) {bouns = b; } @Override public boolean equals (object orethobject) {if (! Super.equals (orheabject)) return false; Менеджер другой = (менеджер) Другой Объект; // Супер равны проверяли, что это и другие принадлежат к одному и тому же возвращению класса Bouns == Другое. Bouns; } @Override public int hashcode () {return super.hashcode () + 17 * new Double (Bouns) .hashcode (); } @Override public String toString () {return super.toString () + "[bouns =" + bouns + "]"; } частные двойные боунс; } Пойдите глубже и разделите его на 2 категории в соответствии с «переопределяет ли класс метод equals ()».
(1) Если класс не переопределяет метод Equals (), когда он сравнивает два объекта через Equals (), на самом деле сравнивает, являются ли два объекта одним и тем же объектом. В настоящее время это эквивалентно сравнению этих двух объектов по "==".
(2) Мы можем переопределить метод Equals () класса, чтобы позволить equals () сравнивать, равны ли два объекта другими способами. Обычная практика такова: если содержимое двух объектов равно, метод equals () возвращает true; В противном случае он возвращает Fasle.
Далее давайте приведем пример, чтобы объяснить две вышеупомянутые ситуации.
1. Случай «не переоценка equals () метод»
Код заключается в следующем (EveryStest1.java):
Импорт java.util.*; импортировать java.lang.comparable;/*** @desc equals () Программа тестирования. */public Class EcountStest1 {public static void main (string [] args) {// Создание 2 новых объектов человека с одним и тем же контентом, // использование равных, чтобы сравнить, являются ли они равным человеком P1 = новый человек ("eee", 100); Человек P2 = новый человек ("eee", 100); System.out.printf («%s/n», p1.equals (p2)); } /*** @desc Person Class. */ частное статическое классовое лицо {int возраст; String name; Public Person (string name, int age) {this.name = name; this.age = возраст; } public String toString () {return name + " -" + age; }}} Результаты работы:
Скопируйте код следующим образом: false
Анализ результатов мы используем P1.Equals (P2), чтобы «сравнить, равны ли P1 и P2». Фактически, метод equals () объекта. Это для сравнения «являются ли P1 и P2 одним и тем же объектом».
Из определений P1 и P2 мы видим, что, хотя их содержание одинаково, они являются двумя разными объектами! Следовательно, результат возврата является ложным.
2. ситуация «перезаписания equals () метод»
Мы модифицируем evelstest1.java выше: переопределите метод evalless ().
Код заключается в следующем (EarningStest2.java):
Импорт java.util.*; импортировать java.lang.comparable;/*** @desc equals () Программа тестирования. */public class evenstest2 {public static void main (string [] args) {// Создание 2 новых объектов человека с одним и тем же контентом, // использование равных, чтобы сравнить, являются ли они равным человеком P1 = новый человек ("eee", 100); Человек P2 = новый человек ("eee", 100); System.out.printf («%s/n», p1.equals (p2)); } /*** @desc Person Class. */ частное статическое классовое лицо {int возраст; String name; Public Person (string name, int age) {this.name = name; this.age = возраст; } public String toString () {return name + " -" + age; } / *** @desc переопределить метод equals* / @override public boolean equals (Object obj) {if (obj == null) {return false; } // Если это один и тот же объект, вернуть true, в противном случае вернуть false if (this == obj) {return true; } // Судите, является ли тип одинаковым if (this.getClass ()! = Obj.getClass ()) {return false; } Person person = (человек) obj; return name.equals (person.name) && age == person.age; }}} Результаты работы:
Скопируйте код следующим образом: true
Анализ результатов:
Мы переопределяем функцию Person's Equals () в EvalStest2.java: Когда имя и возраст объектов двух человек равны, оно возвращает истинность.
Следовательно, результат прогона возвращается правдой.
Сказав это, давайте поговорим о требованиях Java для Equals (). Есть следующие моменты:
Симметрия: если x.equals (y) возвращает «true», то y.equals (x) также должны вернуть «true».
Отражательная способность: x.equals (x) должен вернуть «true».
Аналогия: если x.equals (y) возвращает «true», а y.equals (z) возвращает «true», то z.equals (x) также должен возвращать «true».
Согласованность: если x.equals (y) возвращает «true», если содержимое x и y останется неизменным, независимо от того, сколько раз вы повторяете x.equals (y), возврат будет «истиной».
Непусты, x.equals (null), всегда возвращает «false»; X.Equals (объекты разных типов и x) всегда возвращает «false».
Теперь давайте рассмотрим роль equals (): определить, равны ли два объекта. Когда мы переписываем equals (), невозможно изменить ее функцию!
В чем разница между равным () и ==?
==: его функция - определить, равны ли адреса двух объектов. То есть определить, являются ли два объекта одним и тем же объектом.
equals (): его функция - определить, равны ли два объекта. Однако, как правило, имеет два условия использования (оно было подробно описано в предыдущей части 1):
Случай 1, класс не переопределяет метод equals (). Затем при сравнении двух объектов этого класса через Equals () он эквивалентен сравнению этих двух объектов с помощью "==".
Случай 2, класс переопределяет метод equals (). Как правило, мы переопределяем метод Equals (), чтобы сделать содержимое двух объектов равным; Если их содержимое равное, оно возвращает истину (то есть два объекта считаются равными).
Ниже сравните их различия по примерам.
Код заключается в следующем:
Импорт java.util.*; импортировать java.lang.comparable;/*** @desc equals () Программа тестирования. */public class evenstest3 {public static void main (string [] args) {// Создание 2 новых объектов человека с одним и тем же контентом, // использование равных, чтобы сравнить, являются ли они равным человеком P1 = новый человек ("eee", 100); Человек P2 = новый человек ("eee", 100); System.out.printf ("p1.equals (p2): %s/n", p1.equals (p2)); System.out.printf ("p1 == p2: %s/n", p1 == p2); } /*** @desc Person Class. */ частное статическое классовое лицо {int возраст; String name; Public Person (string name, int age) {this.name = name; this.age = возраст; } public String toString () {return name + " -" + age; } / *** @desc переопределить метод equals* / @override public boolean equals (Object obj) {if (obj == null) {return false; } // Если это один и тот же объект, вернуть true, в противном случае вернуть false if (this == obj) {return true; } // Судите, является ли тип одинаковым if (this.getClass ()! = Obj.getClass ()) {return false; } Person person = (человек) obj; return name.equals (person.name) && age == person.age; }}} Результаты работы:
P1.Equals (P2): truep1 == p2: false
Анализ результатов:
В EvalStest3.java:
(1) P1.Equals (P2)
Это должно определить, равно ли содержимое P1 и P2. Поскольку человек переопределяет метод равного (), и это равное () используется для определения того, равно ли содержимое P1 и P2 точно содержимое P1 и P2; Поэтому вернуть правду.
(2) P1 == P2
Это должно определить, являются ли P1 и P2 одним и тем же объектом. Так как они два новых объекта человека каждый; Поэтому вернуть ложь.