ProgrammationDéveloppeur Java

Expliquez les particularités de la méthode equals() en Java : quand et pourquoi l'override, comment l'implémenter correctement et quels problèmes peuvent survenir en cas d'utilisation incorrecte.

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse

La méthode equals() détermine si deux objets sont "égaux". Par défaut, elle compare les références (c'est-à-dire ==), mais souvent les classes (par exemple, les entités, les objets de valeur) requièrent une comparaison logique basée sur les données.

Quand l'override :

  • Si l'identité logique des objets est importante pour votre classe (par exemple, deux utilisateurs avec le même email — c'est "le même utilisateur")
  • Si l'objet sera stocké dans des collections (par exemple, HashSet) qui utilisent equals (et hashCode)

Exigences :

  • Equals doit être réflexif, symétrique, transitif, cohérent et pour tout x non null, x.equals(null) doit être faux
  • Lors de l'override de equals, il est OBLIGATOIRE d'override hashCode!

Exemple :

public class Person { private String email; @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Person person = (Person) o; return Objects.equals(email, person.email); } @Override public int hashCode() { return Objects.hash(email); } }

Question piégeuse

Si deux objets sont égaux selon equals(), leur hashCode() doit-il toujours être identique ?

Réponse : Oui ! C'est une exigence des contrats Java. Mais l'inverse n'est pas vrai : deux objets avec le même hashCode peuvent ne pas être égaux selon equals() — des collisions peuvent se produire pour différents objets.

Exemple d'erreur :

person1.equals(person2); // vrai person1.hashCode() != person2.hashCode(); // Erreur!

Exemples d'erreurs réelles dues à l'ignorance des subtilités du sujet


Histoire

Dans une application d'entreprise, l'entité Utilisateur a été ajoutée à un HashSet. Equals a été override, hashCode ne l'a pas été. Après modification des champs affectant equals, le HashSet a "perdu" cet objet : une tentative de recherche par méthode contains retournait false, même pour les mêmes données.


Histoire

Dans un projet IoT, les entités étaient temporairement comparées uniquement par id, puis la logique a été changée pour equals en tenant compte du nom. HashMap a commencé à se comporter de manière imprévisible, des duplicatas sont apparus lors de la mise à jour des clés — le contrat equals/hashCode a été violé à cause du mélange des versions d'implémentation.


Histoire

Lors de l'écriture d'une API pour comparer des commandes, deux classes différentes ont implémenté leur propre equals, l'une appelait getClass(), l'autre instanceof. Cela a conduit à une comparaison asymétrique des commandes et à des bugs lors de l'utilisation de collections et de la logique métier.