Maison > Java > javaDidacticiel > le corps du texte

Tutoriel sur la façon d'utiliser la méthode equals() pour déterminer si les objets sont égaux en Java

高洛峰
Libérer: 2017-02-03 13:08:57
original
3064 Les gens l'ont consulté

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;
Copier après la connexion

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;
Copier après la connexion

(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;
Copier après la connexion

Si toutes les sous-classes ont la même sémantique, utilisez instanceof pour détecter

if(!(otherObject instanceof ClassName)) return false;
Copier après la connexion

( 5) Convertir un autre objet en une variable du type correspondant :

ClassName other=(ClassName)otherObject;
Copier après la connexion

(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)
Copier après la connexion

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
Copier après la connexion

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;
}
Copier après la connexion

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;
  }
 }
}
Copier après la connexion

Résultat d'exécution :

false
Copier après la connexion


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;
  }
 }
}
Copier après la connexion

Résultats d'exécution :

true
Copier après la connexion

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;
  }
 }
}
Copier après la connexion

运行结果:

p1.equals(p2) : true
p1==p2 : false
Copier après la connexion

结果分析:
在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中文网!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal