Comment vérifier si deux objets sont égaux en Java

JavaJavaBeginner
Pratiquer maintenant

💡 Ce tutoriel est traduit par l'IA à partir de la version anglaise. Pour voir la version originale, vous pouvez cliquer ici

Introduction

Dans ce laboratoire (lab), vous apprendrez à vérifier si deux objets sont égaux en Java. Nous explorerons la différence fondamentale entre l'utilisation de l'opérateur == et de la méthode equals() pour comparer des objets.

Vous commencerez par utiliser la méthode intégrée equals() pour comparer des objets et comprendre son comportement avec différents types de données. Ensuite, vous apprendrez à redéfinir (override) la méthode equals() dans vos propres classes personnalisées pour définir ce qui constitue l'égalité logique de vos objets. Enfin, vous aborderez la considération importante de la gestion des objets nuls lors de la réalisation de vérifications d'égalité pour éviter les erreurs potentielles de NullPointerException.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL java(("Java")) -.-> java/StringManipulationGroup(["String Manipulation"]) java(("Java")) -.-> java/ProgrammingTechniquesGroup(["Programming Techniques"]) java(("Java")) -.-> java/ObjectOrientedandAdvancedConceptsGroup(["Object-Oriented and Advanced Concepts"]) java(("Java")) -.-> java/SystemandDataProcessingGroup(["System and Data Processing"]) java/StringManipulationGroup -.-> java/strings("Strings") java/ProgrammingTechniquesGroup -.-> java/method_overriding("Method Overriding") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/classes_objects("Classes/Objects") java/SystemandDataProcessingGroup -.-> java/object_methods("Object Methods") subgraph Lab Skills java/strings -.-> lab-560013{{"Comment vérifier si deux objets sont égaux en Java"}} java/method_overriding -.-> lab-560013{{"Comment vérifier si deux objets sont égaux en Java"}} java/classes_objects -.-> lab-560013{{"Comment vérifier si deux objets sont égaux en Java"}} java/object_methods -.-> lab-560013{{"Comment vérifier si deux objets sont égaux en Java"}} end

Utilisation de la méthode equals() pour vérifier l'égalité

Dans cette étape, nous allons explorer comment comparer des objets en Java en utilisant la méthode equals(). Alors que l'opérateur == vérifie si deux références d'objets pointent vers exactement le même objet en mémoire, la méthode equals() est conçue pour vérifier si deux objets sont logiquement égaux, c'est-à-dire s'ils représentent la même valeur ou le même état.

Commençons par créer un simple fichier Java pour illustrer ce concept.

  1. Ouvrez l'WebIDE et assurez-vous que vous êtes dans le répertoire ~/project. Vous pouvez le vérifier en regardant l'invite de commande du terminal ou en tapant pwd puis en appuyant sur Entrée.

  2. Créez un nouveau fichier nommé EqualityDemo.java dans le répertoire ~/project. Vous pouvez le faire en cliquant avec le bouton droit dans l'explorateur de fichiers à gauche et en sélectionnant "Nouveau fichier", puis en tapant EqualityDemo.java.

  3. Ouvrez le fichier EqualityDemo.java dans l'éditeur et collez le code suivant :

    public class EqualityDemo {
        public static void main(String[] args) {
            String str1 = new String("hello");
            String str2 = new String("hello");
            String str3 = str1;
    
            System.out.println("Comparing String objects:");
            System.out.println("str1 == str2: " + (str1 == str2));
            System.out.println("str1.equals(str2): " + str1.equals(str2));
            System.out.println("str1 == str3: " + (str1 == str3));
            System.out.println("str1.equals(str3): " + str1.equals(str3));
    
            System.out.println("\nComparing primitive types (int):");
            int num1 = 10;
            int num2 = 10;
            System.out.println("num1 == num2: " + (num1 == num2));
        }
    }

    Dans ce code :

    • Nous créons deux objets String, str1 et str2, avec le même contenu ("hello") mais en utilisant new String(), ce qui crée des objets distincts en mémoire.
    • Nous créons une troisième référence String, str3, et nous la faisons pointer vers le même objet que str1.
    • Nous utilisons à la fois == et equals() pour comparer str1 et str2, ainsi que str1 et str3.
    • Nous montrons également une comparaison de types primitifs int en utilisant ==. Rappelez-vous que equals() est utilisé pour les objets, pas pour les types primitifs.
  4. Enregistrez le fichier EqualityDemo.java (Ctrl+S ou Cmd+S).

  5. Ouvrez le terminal en bas de l'WebIDE.

  6. Compilez le programme Java en tapant la commande suivante puis en appuyant sur Entrée :

    javac EqualityDemo.java

    S'il n'y a pas d'erreurs, vous ne devriez voir aucun résultat.

  7. Exécutez le programme compilé en tapant la commande suivante puis en appuyant sur Entrée :

    java EqualityDemo

    Vous devriez voir un résultat similaire à ceci :

    Comparing String objects:
    str1 == str2: false
    str1.equals(str2): true
    str1 == str3: true
    str1.equals(str3): true
    
    Comparing primitive types (int):
    num1 == num2: true

    Remarquez que str1 == str2 est false car ils sont des objets différents en mémoire, même s'ils ont le même contenu. Cependant, str1.equals(str2) est true car la méthode equals() de la classe String est redéfinie pour comparer le contenu réel des chaînes. str1 == str3 est true car str3 pointe vers exactement le même objet que str1.

Cela illustre la différence clé entre == (égalité de référence) et equals() (égalité logique) lors de la comparaison d'objets en Java. Pour les types primitifs, == est utilisé pour comparer les valeurs.

Redéfinition de la méthode equals() dans une classe personnalisée

Dans l'étape précédente, nous avons vu comment la méthode equals() fonctionne pour les objets String. La classe String a déjà redéfini (override) la méthode equals() par défaut (héritée de la classe Object) pour fournir une comparaison significative basée sur le contenu.

Cependant, lorsque vous créez vos propres classes personnalisées, la méthode equals() par défaut héritée de Object utilise simplement l'opérateur ==, ce qui signifie qu'elle ne vérifie que l'égalité de référence. Pour comparer les objets de votre classe personnalisée en fonction de leurs attributs (égalité logique), vous devez redéfinir vous-même la méthode equals().

Dans cette étape, nous allons créer une simple classe Person et redéfinir sa méthode equals().

  1. Assurez-vous que vous êtes dans le répertoire ~/project dans l'WebIDE.

  2. Créez un nouveau fichier nommé Person.java dans le répertoire ~/project.

  3. Ouvrez le fichier Person.java et collez le code suivant pour la classe Person :

    public class Person {
        private String name;
        private int age;
    
        public Person(String name, int age) {
            this.name = name;
            this.age = age;
        }
    
        public String getName() {
            return name;
        }
    
        public int getAge() {
            return age;
        }
    
        // La méthode equals() par défaut (héritée de Object) ne vérifie que l'égalité de référence
        // Nous devons la redéfinir pour vérifier l'égalité logique basée sur le nom et l'âge
        @Override
        public boolean equals(Object obj) {
            // Étape 1 : Vérifier si les objets sont la même instance
            if (this == obj) {
                return true;
            }
    
            // Étape 2 : Vérifier si l'objet est null ou d'une classe différente
            if (obj == null || getClass() != obj.getClass()) {
                return false;
            }
    
            // Étape 3 : Convertir l'objet au bon type
            Person person = (Person) obj;
    
            // Étape 4 : Comparer les attributs pertinents
            return age == person.age &&
                   name.equals(person.name); // Utiliser equals() pour comparer les chaînes de caractères
        }
    }

    Dans cette classe Person :

    • Nous avons deux attributs privés : name (de type String) et age (de type int).
    • Nous avons un constructeur pour initialiser ces attributs.
    • Nous avons des méthodes d'accès (getter) pour accéder aux attributs.
    • Nous avons redéfini la méthode equals(). Examinons les étapes à l'intérieur de la méthode equals() redéfinie :
      • if (this == obj) : C'est une optimisation. Si les deux références pointent vers exactement le même objet, ils sont certainement égaux.
      • if (obj == null || getClass() != obj.getClass()) : Cela vérifie si l'objet comparé est null ou s'il n'est pas une instance de la classe Person. Si l'une de ces conditions est vraie, ils ne peuvent pas être égaux.
      • Person person = (Person) obj; : Nous convertissons l'objet générique Object en un objet Person pour pouvoir accéder à ses attributs name et age.
      • return age == person.age && name.equals(person.name); : C'est le cœur de la comparaison logique. Nous vérifions si l'age est le même (en utilisant == pour le type primitif int) et si le name est le même (en utilisant equals() pour les objets String).
  4. Enregistrez le fichier Person.java.

  5. Maintenant, créons un autre fichier, PersonEqualityDemo.java, pour tester notre méthode equals() redéfinie. Créez ce fichier dans le répertoire ~/project.

  6. Ouvrez le fichier PersonEqualityDemo.java et collez le code suivant :

    public class PersonEqualityDemo {
        public static void main(String[] args) {
            Person person1 = new Person("Alice", 30);
            Person person2 = new Person("Alice", 30);
            Person person3 = new Person("Bob", 25);
            Person person4 = person1;
    
            System.out.println("Comparing Person objects:");
            System.out.println("person1 == person2: " + (person1 == person2));
            System.out.println("person1.equals(person2): " + person1.equals(person2));
            System.out.println("person1 == person3: " + (person1 == person3));
            System.out.println("person1.equals(person3): " + person1.equals(person3));
            System.out.println("person1 == person4: " + (person1 == person4));
            System.out.println("person1.equals(person4): " + person1.equals(person4));
        }
    }

    Dans cette classe de démonstration, nous créons plusieurs objets Person et les comparons en utilisant à la fois l'opérateur == et notre méthode equals() redéfinie.

  7. Enregistrez le fichier PersonEqualityDemo.java.

  8. Ouvrez le terminal. Assurez-vous que vous êtes dans le répertoire ~/project.

  9. Compilez les deux fichiers Java. Vous pouvez compiler plusieurs fichiers à la fois :

    javac Person.java PersonEqualityDemo.java

    Cela devrait créer les fichiers Person.class et PersonEqualityDemo.class.

  10. Exécutez le programme de démonstration :

    java PersonEqualityDemo

    Vous devriez voir un résultat similaire à ceci :

    Comparing Person objects:
    person1 == person2: false
    person1.equals(person2): true
    person1 == person3: false
    person1.equals(person3): false
    person1 == person4: true
    person1.equals(person4): true

    Comme prévu, person1 == person2 est false car ils sont des objets distincts, mais person1.equals(person2) est true car leur name et leur age sont les mêmes selon notre méthode redéfinie. person1 et person3 ne sont pas égaux selon les deux comparaisons. person1 et person4 sont égaux selon les deux comparaisons car ils font référence au même objet.

En redéfinissant la méthode equals(), vous définissez ce que signifie "égal" pour les objets de votre classe personnalisée en fonction de leur état logique plutôt que simplement de leur emplacement mémoire.

Gestion des objets null dans les comparaisons d'égalité

Dans l'étape précédente, nous avons réussi à redéfinir la méthode equals() dans notre classe Person pour comparer les objets en fonction de leurs attributs. Un aspect crucial de l'écriture de méthodes equals() robustes est la gestion des valeurs null potentielles. Si vous essayez d'appeler une méthode sur un objet null, cela entraînera une NullPointerException, qui est une erreur courante en Java.

Notre méthode equals() redéfinie dans Person.java inclut déjà une vérification pour null : if (obj == null || getClass() != obj.getClass()). C'est la manière standard de gérer le cas où l'objet comparé est null.

Dans cette étape, nous allons démontrer ce qui se passe lorsqu'on compare un objet à null et confirmer que notre méthode equals() le gère correctement.

  1. Assurez-vous que vous êtes dans le répertoire ~/project dans l'WebIDE.

  2. Ouvrez le fichier PersonEqualityDemo.java que vous avez créé dans l'étape précédente.

  3. Ajoutez les lignes suivantes à la méthode main, après les instructions de comparaison existantes :

    System.out.println("\nComparing with null:");
    System.out.println("person1.equals(null): " + person1.equals(null));

    Ce code ajoute simplement une comparaison de person1 avec null.

  4. Enregistrez le fichier PersonEqualityDemo.java.

  5. Ouvrez le terminal. Assurez-vous que vous êtes dans le répertoire ~/project.

  6. Compilez le fichier PersonEqualityDemo.java modifié :

    javac PersonEqualityDemo.java

    Rappelez-vous que vous n'avez besoin de recompiler que les fichiers que vous avez modifiés. Comme Person.java n'a pas été modifié dans cette étape, nous n'avons besoin de compiler que PersonEqualityDemo.java.

  7. Exécutez le programme compilé :

    java PersonEqualityDemo

    Vous devriez maintenant voir le résultat précédent suivi de la nouvelle comparaison avec null :

    Comparing Person objects:
    person1 == person2: false
    person1.equals(person2): true
    person1 == person3: false
    person1.equals(person3): false
    person1 == person4: true
    person1.equals(person4): true
    
    Comparing with null:
    person1.equals(null): false

    Le résultat person1.equals(null): false confirme que notre méthode equals() redéfinie gère correctement la comparaison avec null et retourne false sans lancer de NullPointerException. Cela est dû au fait que la ligne if (obj == null || getClass() != obj.getClass()) dans la méthode equals() de notre classe Person vérifie null avant d'essayer d'accéder à tout attribut de obj.

Gérer les valeurs null est une partie essentielle de l'écriture de code robuste en Java, surtout lorsqu'il s'agit de comparaisons d'objets. Toujours inclure une vérification de null au début de votre méthode equals() redéfinie.

Résumé

Dans ce laboratoire, nous avons appris à vérifier si deux objets sont égaux en Java. Nous avons commencé par comprendre la différence entre l'opérateur ==, qui vérifie l'égalité de référence, et la méthode equals(), qui vérifie l'égalité logique. Nous avons démontré cela en utilisant des objets String et des types primitifs, en observant comment == se comporte différemment de equals() pour les objets.

Nous avons ensuite exploré comment redéfinir (override) la méthode equals() dans des classes personnalisées pour définir nos propres critères d'égalité d'objets. Cela est crucial pour garantir que nos objets personnalisés sont comparés en fonction de leur contenu ou de leur état plutôt que simplement de leur emplacement mémoire. Enfin, nous avons appris l'importance de gérer les objets null dans la méthode equals() pour éviter les NullPointerException et assurer des vérifications d'égalité robustes.