La méthode équivalente dans la classe d'objets est utilisée pour détecter si un objet est égal à un autre objet. Dans la classe d'objets, cette méthode détermine si deux objets ont la même référence. Si les deux objets ont la même référence, ils doivent être égaux. À partir de ce point de vue, il est raisonnable de l'utiliser comme opération par défaut. Cependant, pour la plupart des classes, ce jugement n'a pas de sens. Par exemple, il est tout à fait dénué de sens de comparer si deux streams imprimés sont égaux de cette manière. Cependant, il est souvent nécessaire de détecter l'égalité des états de deux objets. Si les états des deux objets sont égaux, les deux objets sont considérés comme égaux. Par conséquent, en général, les comparaisons équivalent à réécrire dans les classes personnalisées.
Voici quelques suggestions pour écrire une méthode perfect Equals ():
(1) Le paramètre explicite est nommé autre objet, et il doit être converti en une variable appelée autre plus tard
(2) détecter si celle et d'autres objet se réfèrent au même objet:
if (this == autre objet) renvoie true;
Cette déclaration n'est qu'une optimisation. En fait, c'est une forme qui est souvent adoptée. Parce que le calcul de cette équation est beaucoup moins cher que de comparer les champs dans une classe un par un.
(3) Vérifiez si AUTRESOBRIET est nul et si nul, renvoyez false. Ce test est nécessaire.
if (autreobject == null) return false;
(4) Comparez si cet autre objet appartient à la même classe. Si la sémantique de l'égalité change dans chaque sous-classe, utilisez getClass () pour le détecter, qui se prend comme la classe cible
if (getClass ()! = autreobject.getClass ()) return false;
Si toutes les sous-classes ont la même sémantique, utilisez l'instance de détection
if (! (AutreObject instanceof className)) renvoie false;
(5) Convertir autre objet en une variable du type correspondant:
ClassName autre = (className) autreObject;
(6) Commencez maintenant à comparer tous les domaines qui doivent être comparés. Use == pour comparer le domaine de type de base et utiliser égaux pour comparer le domaine de l'objet. Renvoie True si tous les champs correspondent, sinon renvoyez false;
return field1 == autre.field1 && field2.equals (autre.field2)
Si égal est redéfini dans une sous-classe, vous devez inclure l'appel super.equals (autre). Si la détection échoue, il est impossible d'être égal. Si les domaines de la superclasse sont égaux, comparez les domaines d'instance dans la sous-classe.
Pour les champs de type tableau, vous pouvez utiliser la méthode des tableaux statiques. Pour détecter si les éléments correspondants sont égaux.
Jetons un coup d'œil à 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 parce que les constantes de chaîne sont partagées en java, il n'y a qu'un seul System.out.out.println (a == c); // faux a et c appartiennent à 2 objets différents System.out.println (a.equals (c)); // Vrai puisque la méthode égale de l'objet String compare les valeurs de l'objet, il renvoie true. (Différent de la méthode égaux de l'objet) System.out.println (c == d); // Faux Bien que les valeurs des objets soient les mêmes, elles appartiennent à 2 objets différents, ils ne sont donc pas System.out.out.println (C.Equals (D)); // vraiAutrement dit, lorsque vous comparez les constantes de chaîne, c'est la même chose que le résultat renvoyé par Equals. Lorsque vous souhaitez comparer la valeur de l'objet String, utilisez les égaux.
Voir un exemple d'utilisation des égaux:
Package Chapitre05. Equalstest; import java.util. *; classe publique EqualSest {public static void main (String [] args) {employé Alice1 = nouvel employé ("Alice Adams", 75000, 1987, 12, 15); Employé Alice2 = Alice1; // référence au même objet Employé Alice3 = nouvel employé ("Alice Adams", 75000, 1987, 12, 15); Employé Bob = nouvel employé ("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 ()); }} Employé de classe {employé public (String n, double s, int an, int mois, int day) {name = n; salaire = s; GregorianCalendar Calendar = New GregorianCalendar (année, mois, jour); HIREDAY = Calendar.GetTime (); } public String getName () {Nom de retour; } public double getSalary () {return salaire; } public Date Gethireday () {return HiredAy; } public void Raisalary (double bypercent) {double relance = salaire * bypercent / 100; salaire + = augmentation; } @Override public booléan equals (objet autre objet) {// un test rapide pour voir si les objets sont identifiés si (this == autreObject) renvoie true; // doit renvoyer false si le paramètre explicite est null if (autreobject == null) renvoie false; // Si les classes ne correspondent pas, ils ne peuvent pas être égaux si (getClass ()! = AutreObject.getClass ()) renvoie false; // Nous savons maintenant que d'autres objets sont un employé non null employé autre = (employé) autre objet; // Testez si les champs ont identifié les valeurs identifiées nom.equals (autre.name) && salaire == autre.salary && hirreday.equals (alther.hireday); } @Override public int hashcode () {return 7 * name.hashcode () + 11 * new double (salaire) .hashcode () + 13 * Hireday.hashcode (); } @Override public String toString () {return getClass (). GetName () + "[name =" + name + ", salary =" + salaire + ", embaucheday =" + hireday + "]"; } nom de chaîne privée; Salaire double privé; Date privée Hireday; } Gestionnaire de classe étend Employee {Public Manager (String n, Double S, int an, int mois, int day) {super (n, s, année, mois, jour); BOUNS = 0; } @Override public double getalary () {double basesalary = super.getsalary (); Basésalaire de retour + Bounns; } public void setBouns (double b) {Bouns = b; } @Override public boolean equals (objet autre objet) {if (! Super.equals (autreobject)) return false; Manager autre = (Manager) autreObject; // super égal a vérifié que cet et l'autre appartiennent à la même classe Bounns de retour == autre.bouns; } @Override public int hashcode () {return super.hashcode () + 17 * new Double (Bouns) .HashCode (); } @Override public String toString () {return super.toString () + "[Bouns =" + Bouns + "]"; } Bounns doubles privés; } Allez plus profondément et divisez-le en 2 catégories selon "si la classe remplace la méthode equals ()".
(1) Si une classe ne remplace pas la méthode equals (), lorsqu'elle compare les deux objets via equals (), il compare réellement si les deux objets sont le même objet. À l'heure actuelle, il équivaut à comparer ces deux objets par "==".
(2) Nous pouvons remplacer la méthode equals () de la classe pour laisser Equals () comparer si deux objets sont égaux par d'autres moyens. La pratique habituelle est: si le contenu de deux objets est égal, la méthode equals () renvoie true; Sinon, il renvoie Fasle.
Ensuite, donnons un exemple pour expliquer les deux situations ci-dessus.
1. Le cas de "ne pas remplacer la méthode equals ()"
Le code est le suivant (Equalstest1.java):
Importer java.util. *; Importer java.lang.comparable; / ** * @desc equals () Programme de test. * / classe publique EqualSTest1 {public static void main (String [] args) {// Créer 2 objets de nouvelle personne avec le même contenu, // Utiliser est égal pour comparer s'il s'agit d'une personne égale p1 = nouvelle personne ("EEE", 100); Personne P2 = nouvelle personne ("EEE", 100); System.out.printf ("% S / N", P1.Equals (P2)); } / ** * Classe de personne @descs. * / Personne de classe statique privée {int Age; Nom de chaîne; Personne publique (nom de chaîne, int age) {this.name = name; this.age = âge; } public String toString () {Nom de retour + "-" + âge; }}} Résultats en cours:
Copiez le code comme suit: faux
Analyse des résultats Nous utilisons P1.Equals (P2) pour "comparer si P1 et P2 sont égaux". En fait, la méthode equals () d'objet.java est appelée, c'est-à-dire le (p1 == p2) appelé. C'est pour comparer "si P1 et P2 sont le même objet".
D'après les définitions de P1 et P2, nous pouvons voir que bien que leur contenu soit le même, ce sont deux objets différents! Par conséquent, le résultat de retour est faux.
2. La situation de "Méthode d'écrasement égal ()"
Nous modifions le Equalstest1.java ci-dessus: remplacer la méthode equals ().
Le code est le suivant (Equalstest2.java):
Importer java.util. *; Importer java.lang.comparable; / ** * @desc equals () Programme de test. * / classe publique EqualSTest2 {public static void main (String [] args) {// Créer 2 objets de nouvelle personne avec le même contenu, // Utiliser est égal pour comparer s'il s'agit d'une personne égale p1 = nouvelle personne ("EEE", 100); Personne P2 = nouvelle personne ("EEE", 100); System.out.printf ("% S / N", P1.Equals (P2)); } / ** * Classe de personne @descs. * / Personne de classe statique privée {int Age; Nom de chaîne; Personne publique (nom de chaîne, int age) {this.name = name; this.age = âge; } public String toString () {Nom de retour + "-" + âge; } / ** * @DESC Override est égal à la méthode * / @Override public boolean equals (objet obj) {if (obj == null) {return false; } // Si c'est le même objet, renvoie true, sinon renvoie false if (this == obj) {return true; } // juger si le type est le même si (this.getClass ()! = Obj.getClass ()) {return false; } Personne personne = (personne) obj; retour name.equals (personne.name) && age == Person.age; }}} Résultats en cours:
Copiez le code comme suit: vrai
Analyse des résultats:
Nous l'emportons sur la fonction equals () de la personne dans EqualSTest2.Java: Lorsque le nom et l'âge des deux objets de deux personnes sont égaux, il renvoie vrai.
Par conséquent, le résultat d'exécution renvoie true.
Cela dit, parlons 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éflectivité: x.equals (x) doit retourner "true".
Analogie: si x.equals (y) renvoie "true", et y.equals (z) renvoie "true", alors z.equals (x) devrait également renvoyer "true".
Cohérence: Si x.equals (y) revient "vrai", tant que le contenu de X et Y reste inchangé, peu importe combien de fois vous répétez x.equals (y), le retour sera "vrai".
Non vide, x.equals (null), renvoie toujours "false"; x.equals (objets de différents types et x) renvoie toujours "false".
Maintenant, passons en revue le rôle d'Equals (): Déterminez si deux objets sont égaux. Lorsque nous réécrivons equals (), il est impossible de changer sa fonction!
Quelle est la différence entre equals () et ==?
==: Sa fonction consiste à déterminer si les adresses de deux objets sont égales. Autrement dit, déterminer si les deux objets sont le même objet.
equals (): sa fonction est de déterminer si deux objets sont égaux. Cependant, il a généralement deux conditions d'utilisation (elle a été décrite en détail dans la partie précédente 1):
Cas 1, la classe ne remplace pas la méthode equals (). Ensuite, lorsque vous comparez deux objets de cette classe via equals (), il équivaut à comparer ces deux objets par "==".
Cas 2, la classe remplace la méthode equals (). Généralement, nous remplacons la méthode equals () pour rendre le contenu de deux objets égaux; Si leur contenu est égal, il renvoie vrai (c'est-à-dire que les deux objets sont considérés comme égaux).
Ci-dessous, comparez leurs différences par exemples.
Le code est le suivant:
Importer java.util. *; Importer java.lang.comparable; / ** * @desc equals () Programme de test. * / classe publique EqualSTest3 {public static void main (String [] args) {// Créer 2 objets de nouvelle personne avec le même contenu, // Utiliser égaux pour comparer s'il est égal P1 = nouvelle personne ("EEE", 100); Personne P2 = nouvelle personne ("EEE", 100); System.out.printf ("p1.equals (p2):% s / n", p1.equals (p2)); System.out.printf ("p1 == p2:% s / n", p1 == p2); } / ** * Classe de personne @descs. * / Personne de classe statique privée {int Age; Nom de chaîne; Personne publique (nom de chaîne, int age) {this.name = name; this.age = âge; } public String toString () {Nom de retour + "-" + âge; } / ** * @DESC Override est égal à la méthode * / @Override public boolean equals (objet obj) {if (obj == null) {return false; } // Si c'est le même objet, renvoie true, sinon renvoie false if (this == obj) {return true; } // juger si le type est le même si (this.getClass ()! = Obj.getClass ()) {return false; } Personne personne = (personne) obj; retour name.equals (personne.name) && age == Person.age; }}} Résultats en cours:
p1.Equals (p2): truep1 == p2: faux
Analyse des résultats:
Dans Equalstest3.java:
(1) P1.Equals (P2)
Il s'agit de déterminer si le contenu de P1 et P2 est égal. Parce que la personne remplace la méthode equals (), et cela Equal () est utilisé pour déterminer si le contenu de P1 et P2 est égal, exactement le contenu de P1 et P2 est égal; Par conséquent, rendez-vous vrai.
(2) P1 == P2
Il s'agit de déterminer si P1 et P2 sont le même objet. Puisqu'ils sont deux nouveaux objets de personne chacun; Par conséquent, retourne false.