La méthode equals de la classe Object est utilisée pour détecter si un objet est égal à un autre objet. Dans la classe Object, cette méthode détermine si deux objets ont la même référence. Si deux objets ont la même référence, ils doivent être égaux. De ce point de vue, il est logique d’en faire l’action par défaut. Cependant, pour la plupart des classes, ce jugement n'a pas de sens. Par exemple, comparer deux PrintStreams de cette manière n'a aucun sens. Or, il est souvent nécessaire de détecter l’égalité des états de deux objets. Si les états de deux objets sont égaux, les deux objets sont considérés comme égaux. Par conséquent, la comparaison égale doit être remplacée dans les classes personnalisées.
Ce qui suit sont des suggestions pour écrire une méthode parfaite equals() :
(1) Le paramètre explicite est nommé otherObject, qui doit être converti en une variable appelée other plus tard
(2) Vérifiez si this et otherObject font référence au même objet :
if(this==otherObject) return true;
Cette instruction n'est qu'une optimisation. En fait, c’est une forme souvent adoptée. Parce que calculer cette équation coûte beaucoup moins cher que comparer les champs de la classe un par un.
(3) Vérifiez si otherObject est nul S'il est nul, renvoyez false. Ce test est très nécessaire.
if(otherObject==null) return false;
(4) Comparez si this et otherObject appartiennent à la même classe. Si la sémantique de equals change dans chaque sous-classe, utilisez getClass() pour le détecter Self. classe cible
if(getClass()!=otherObject.getClass()) return false;
Si toutes les sous-classes ont la même sémantique, utilisez instanceof pour détecter
if(!(otherObject instanceof ClassName)) return false;
( 5) Convertir un autre objet en une variable du type correspondant :
ClassName other=(ClassName)otherObject;
(6) Commencez maintenant à comparer tous les champs qui doivent être comparés. Utilisez == pour comparer les champs de type de base et égal pour comparer les champs d'objet. Si tous les champs correspondent, retournez true, sinon retournez false
return field1==other.field1&&field2.equals(other.field2)
Si equals est redéfini dans une sous-classe, cela doit inclure l'appel de super.equals(other) ; Si le test échoue, l’égalité est impossible. Si les champs de la superclasse sont égaux, les champs d'instance de la sous-classe sont comparés.
Pour les champs de type tableau, vous pouvez utiliser la méthode statique Arrays.equals pour vérifier si les éléments correspondants sont égaux.
Regardons quelques exemples de comparaison de chaînes :
String a = "abc"; String b = "abc"; String c = new String("abc"); String d = new String("abc"); System.out.println(a == b); // true 因为JAVA中字符串常量是共享的,只有一个拷贝 System.out.println(a == c); // false a和c属于2个不同的对象 System.out.println(a.equals(c)); // true 由于String对象的equals方法比较的是对象中的值,所以返回true。(和Object的equals方法不同) System.out.println(c==d); // false c和d虽然对象内的值相同,但属于2个不同的对象,所以不相等 System.out.println(c.equals(d)); // true
En termes simples, lorsque vous comparez des constantes de chaîne, égal renvoie le même résultat que égal à. souhaitez comparer les valeurs des objets chaîne.
Regardez un exemple d'utilisation d'égaux :
package chapter05.EqualsTest; import java.util.*; public class EqualsTest { public static void main(String[] args) { Employee alice1 = new Employee("Alice Adams", 75000, 1987, 12, 15); Employee alice2 = alice1; // reference the same object Employee alice3 = new Employee("Alice Adams", 75000, 1987, 12, 15); Employee bob = new Employee("Bob Brandson", 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()); } } class Employee { public Employee(String n, double s, int year, int month, int day) { name = n; salary = s; GregorianCalendar calendar = new GregorianCalendar(year, month, day); hireDay = calendar.getTime(); } public String getName() { return name; } public double getSalary() { return salary; } public Date getHireDay() { return hireDay; } public void raiseSalary(double byPercent) { double raise = salary * byPercent / 100; salary += raise; } @Override public boolean equals(Object otherObject) { // a quick test to see if the objects are identical if (this == otherObject) return true; // must return false if the explicit parameter is null if (otherObject == null) return false; // if the classed don't match,they can't be equal if (getClass() != otherObject.getClass()) return false; // now we know otherObject is a non-null Employee Employee other = (Employee) otherObject; // test whether the fields hava identical values return name.equals(other.name) && salary == other.salary && hireDay.equals(other.hireDay); } @Override public int hashCode() { return 7 * name.hashCode() + 11 * new Double(salary).hashCode() + 13 * hireDay.hashCode(); } @Override public String toString() { return getClass().getName() + "[name=" + name + ",salary=" + salary + ",hireDay=" + hireDay + "]"; } private String name; private double salary; private Date hireDay; } class Manager extends Employee { public Manager(String n, double s, int year, int month, int day) { super(n, s, year, month, day); bouns = 0; } @Override public double getSalary() { double baseSalary = super.getSalary(); return baseSalary + bouns; } public void setBouns(double b) { bouns = b; } @Override public boolean equals(Object otherObject) { if (!super.equals(otherObject)) return false; Manager other = (Manager) otherObject; // super equals checked that this and other belong to the same class return bouns == other.bouns; } @Override public int hashCode() { return super.hashCode() + 17 * new Double(bouns).hashCode(); } @Override public String toString() { return super.toString() + "[bouns=" + bouns + "]"; } private double bouns; }
Allez plus loin
Ce qui suit est divisé en 2 catégories selon "si la classe couvre les égaux () méthode" .
(1) Si une classe ne couvre pas la méthode equals(), lorsqu'elle compare deux objets via equals(), elle compare en fait si les deux objets sont le même objet. À ce stade, cela équivaut à comparer les deux objets via "==".
(2) Nous pouvons remplacer la méthode equals() de la classe pour laisser equals() comparer si deux objets sont égaux via d'autres méthodes. L'approche habituelle est la suivante : si les contenus des deux objets sont égaux, la méthode equals() renvoie true sinon, renvoie fasle ;
Ce qui suit est un exemple pour illustrer les deux situations ci-dessus.
1. Cas "La méthode equals() n'est pas couverte"
Le code est le suivant (EqualsTest1.java) :
import java.util.*; import java.lang.Comparable; /** * @desc equals()的测试程序。 */ public class EqualsTest1{ public static void main(String[] args) { // 新建2个相同内容的Person对象, // 再用equals比较它们是否相等 Person p1 = new Person("eee", 100); Person p2 = new Person("eee", 100); System.out.printf("%s\n", p1.equals(p2)); } /** * @desc Person类。 */ private static class Person { int age; String name; public Person(String name, int age) { this.name = name; this.age = age; } public String toString() { return name + " - " +age; } } }
Résultat d'exécution :
false
Analyse des résultats
Nous utilisons p1.equals(p2) pour "comparer si p1 et p2 sont égaux". En fait, la méthode equals() de Object.java est appelée, c'est-à-dire que (p1==p2) est appelé. Il compare "si p1 et p2 sont le même objet".
D'après les définitions de p1 et p2, nous savons que bien qu'ils aient le même contenu, ce sont deux objets différents ! Le résultat renvoyé est donc faux.
2. Le cas du "remplacement de la méthode equals()"
Nous modifions le EqualsTest1.java ci-dessus : remplaçons la méthode equals().
Le code est le suivant (EqualsTest2.java) :
import java.util.*; import java.lang.Comparable; /** * @desc equals()的测试程序。 */ public class EqualsTest2{ public static void main(String[] args) { // 新建2个相同内容的Person对象, // 再用equals比较它们是否相等 Person p1 = new Person("eee", 100); Person p2 = new Person("eee", 100); System.out.printf("%s\n", p1.equals(p2)); } /** * @desc Person类。 */ private static class Person { int age; String name; public Person(String name, int age) { this.name = name; this.age = 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 = (Person)obj; return name.equals(person.name) && age==person.age; } } }
Résultats d'exécution :
true
Analyse des résultats :
Nous sommes en EqualsTest2.java La fonction equals() de Person a été réécrite : lorsque le nom et l'âge de deux objets Person sont égaux, true est renvoyé.
Par conséquent, le résultat en cours renvoie vrai.
En parlant de cela, parlons en passant des exigences de Java pour Equals(). Il y a les points suivants :
Symétrie : Si x.equals(y) renvoie "true", alors y.equals(x) devrait également renvoyer "true".
Réfléchissant : x.equals(x) doit renvoyer "true".
Analogie : si x.equals(y) renvoie "true" et que y.equals(z) renvoie "true", alors z.equals(x) devrait également renvoyer "true".
Cohérence : Si x.equals(y) renvoie "true", tant que le contenu de x et y reste inchangé, peu importe le nombre de fois que vous répétez x.equals(y), le retour sera "true" .
Non-vide, x.equals(null), renvoie toujours "false" ; x.equals (un objet d'un type différent de x) renvoie toujours "false".
Revoyons maintenant le rôle de equals() : pour déterminer si deux objets sont égaux. Quand on réécrit equals(), il ne faut pas changer sa fonction !
equals() 与 == 的区别是什么?
== : 它的作用是判断两个对象的地址是不是相等。即,判断两个对象是不是同一个对象。
equals() : 它的作用也是判断两个对象是否相等。但它一般有两种使用情况(前面第1部分已详细介绍过):
情况1,类没有覆盖equals()方法。则通过equals()比较该类的两个对象时,等价于通过“==”比较这两个对象。
情况2,类覆盖了equals()方法。一般,我们都覆盖equals()方法来两个对象的内容相等;若它们的内容相等,则返回true(即,认为这两个对象相等)。
下面,通过示例比较它们的区别。
代码如下:
import java.util.*; import java.lang.Comparable; /** * @desc equals()的测试程序。 */ public class EqualsTest3{ public static void main(String[] args) { // 新建2个相同内容的Person对象, // 再用equals比较它们是否相等 Person p1 = new Person("eee", 100); Person p2 = new Person("eee", 100); System.out.printf("p1.equals(p2) : %s\n", p1.equals(p2)); System.out.printf("p1==p2 : %s\n", p1==p2); } /** * @desc Person类。 */ private static class Person { int age; String name; public Person(String name, int age) { this.name = name; this.age = 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 = (Person)obj; return name.equals(person.name) && age==person.age; } } }
运行结果:
p1.equals(p2) : true p1==p2 : false
结果分析:
在EqualsTest3.java 中:
(1) p1.equals(p2)
这是判断p1和p2的内容是否相等。因为Person覆盖equals()方法,而这个equals()是用来判断p1和p2的内容是否相等,恰恰p1和p2的内容又相等;因此,返回true。
(2) p1==p2
这是判断p1和p2是否是同一个对象。由于它们是各自新建的两个Person对象;因此,返回false。
更多Java中判断对象是否相等的equals()方法使用教程相关文章请关注PHP中文网!