Si deux objets sont égaux selon equals, ils doivent renvoyer le même hashCode ; des objets différents peuvent partager un hash mais idéalement non. Cassez ce contrat et les collections à base de hash déraillent : un objet placé dans une HashMap devient introuvable parce que la recherche va dans un autre bucket. equals doit aussi être réflexif, symétrique, transitif et cohérent, et modifier un champ utilisé dans le hash après l'insertion perd l'entrée tout aussi efficacement.
Pourquoi les recruteurs posent cette question
C'est une vérification des fondamentaux qui prédit de vrais bugs, surtout dans les bases de code qui utilisent des entités comme clés de map ou dans des sets. Le recruteur veut entendre l'implication à sens unique énoncée correctement, plus l'échec concret : un set qui contient un élément qu'il ne retrouve pas. Les relances vont souvent vers les entités JPA, où equals sur un id généré est un piège classique, et vers les records, qui génèrent les deux pour vous.
Comment structurer votre réponse
- Énoncez le contrat comme une implication, pas une équivalence.
- Décrivez l'échec concret dans une HashMap ou un HashSet.
- Mentionnez la mutabilité des champs utilisés dans le hash.
- Dites ce que vous faites en pratique : records, ou une clé métier stable.
Exemple de réponse
La règle est à sens unique : des objets égaux doivent avoir des hash codes égaux, mais des hash codes égaux n'impliquent pas l'égalité, ce qui explique qu'une map appelle quand même equals à l'intérieur du bucket. Si je redéfinis equals et que j'oublie hashCode, deux objets égaux atterrissent dans des buckets différents, donc je peux mettre quelque chose dans un HashSet puis voir contains renvoyer false pour un objet identique. La version plus subtile, c'est la mutation. Si un champ utilisé dans le hash change après que l'objet est dans un set, l'entrée est désormais dans le mauvais bucket et elle est perdue de fait, ce qui se manifeste comme une fuite mémoire puisqu'elle ne peut plus être retirée non plus. En pratique j'utilise des records pour les types valeur, comme ça les deux sont générés et cohérents. Pour les entités JPA je fais attention, parce qu'utiliser un id généré signifie que equals change quand l'entité est persistée, donc une entité dans un HashSet avant le flush ne se comporte plus pareil après. J'utilise une clé naturelle ou métier stable quand il y en a une, et sinon j'évite de mettre des entités non sauvegardées dans des collections à base de hash.
Vous passez cet entretien bientôt ? GhostPilot écoute votre appel en direct, repère la question dès qu'elle est posée et affiche une réponse structurée à l'écran en temps réel. Essayez-le lors de votre prochain entretien blanc, ou prenez un Session Pass à $29, sans abonnement, pour le jour J.
Voir comment ça marcheQuestions de relance à prévoir
- Comment implémenteriez-vous equals pour une entité JPA avec un id généré ?
- Que génère un record pour vous, et quand n'est-ce pas ce que vous voulez ?
- Pourquoi une mauvaise fonction de hachage dégrade-t-elle une HashMap même si elle est correcte ?
Autres questions pour Développeur Java
Votre recruteur posera sa propre version de celle-ci. Collez votre véritable fiche de poste dans le Question Predictor gratuit et obtenez les 20 questions que ce poste a le plus de chances de poser, avec ce que chacune cherche vraiment à sonder.
Prédire mes questions