IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Java Discussion :

Redéfinition de equals


Sujet :

Langage Java

  1. #1
    Candidat au Club
    Inscrit en
    Mars 2006
    Messages
    2
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 2
    Par défaut Redéfinition de equals
    bonjour

    je suis à redéfinir equals
    voici donc mon code,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    public boolean equals(Object name)
    {
         if (this.nom.equals(((Humain)name).nom))
              System.out.println("Identique");
         else
              System.out.println("Non identique");
         return;
    }
    est-ce une bonne méthode? si oui comment faire pour retourner soit le mot identique ou non identique lorsque je ferai la comparaison.
    si non comment puis-je le faire

    merci!

  2. #2
    Membre éprouvé
    Avatar de mavina
    Homme Profil pro
    Développeur Java
    Inscrit en
    Octobre 2004
    Messages
    1 812
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : Chine

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2004
    Messages : 1 812
    Par défaut
    Bonjour,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    public boolean equals(Object o)
    {
      Humain temp=(Humain)o;
      if (this.nom.equals(temp.nom))
        return true;
      return false;
    }
    equals retourne un boolean, vrai si les deux objets sont égaux, faux sinon.

  3. #3
    Membre chevronné


    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    7 855
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 7 855
    Par défaut
    Quelques améliorations :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    public boolean equals(Object o)
    {
      try {
         Humain temp=(Humain)o;
         if (this.nom != null) return this.nom.equals(temp.nom);
      } catch (ClassCastException e) { //on peut aussi laisser remonter l'exception ....
     
      }
      return false;
    }

  4. #4
    Expert confirmé


    Profil pro
    Inscrit en
    Mai 2003
    Messages
    3 240
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 3 240
    Par défaut
    Citation Envoyé par Ricky81
    Quelques améliorations :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    public boolean equals(Object o)
    {
      try {
         Humain temp=(Humain)o;
         if (this.nom != null) return this.nom.equals(temp.nom);
      } catch (ClassCastException e) { //on peut aussi laisser remonter l'exception ....
     
      }
      return false;
    }
    1) Ne jamais remonter une exception de type ClassCast dans un equals.
    Si c'est pas une classe de type Humain, tu retourne false.

    2) Ne pas oublier d'implementer la méthode qui va de paire avec equals (hashcode) pour mieux distribuer les objets dans les Hashtable, HashMap et autres

  5. #5
    Membre chevronné


    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    7 855
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 7 855
    Par défaut
    Citation Envoyé par vbrabant
    2) Ne pas oublier d'implementer la méthode qui va de paire avec equals (hashcode) pour mieux distribuer les objets dans les Hashtable, HashMap et autres
    Sans oublier la méthode compareTo (interface Comparable) pour les tris dans les collections

  6. #6
    Membre émérite Avatar de Pollux
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    706
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Suisse

    Informations forums :
    Inscription : Avril 2005
    Messages : 706
    Par défaut
    Citation Envoyé par Ricky81
    Sans oublier la méthode compareTo (interface Comparable) pour les tris dans les collections
    Mais non il ne me semble pas. Si l'on surcharge la méthode equals il faut redéfinir également hashcode mais compareTo ce n'est pas du tout obligé! Cette méthode est définie lorsque la classe implémente Comparable mais autrement pas.

  7. #7
    Membre expérimenté Avatar de @ldehan
    Profil pro
    Développeur Java
    Inscrit en
    Mars 2004
    Messages
    215
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2004
    Messages : 215
    Par défaut
    Une petite question concernant hashCode().

    Citation Envoyé par Javadoc Object.hashCode()
    As much as is reasonably practical, the hashCode method defined by class Object does return distinct integers for distinct objects. (This is typically implemented by converting the internal address of the object into an integer, but this implementation technique is not required by the JavaTM programming language.)
    quel est l'interet de redefinir hashCode(), pourquoi ne pas utliser celle de Object qui doit fonctionner tout le temps ?

    je n'ai pas tester et je n'ai jamais utiliser volontairement hashcode(), je ne l'ai d'ailleurs jamais redéfini... (c'est grave docteur ? ? ?)

    je pose la question parce qu'au programme des certifications java :
    Citation Envoyé par Sun Certified Programmer for the Java 2 Platform, Standard Edition 5.0
    Distinguish between correct and incorrect overrides of corresponding hashCode and equals methods, and explain the difference between == and the equals method.

  8. #8
    Membre éprouvé
    Avatar de Deadpool
    Homme Profil pro
    Inscrit en
    Novembre 2005
    Messages
    1 312
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Novembre 2005
    Messages : 1 312
    Par défaut
    A noter aussi que tu peux ajouter une petite optimisation au début de ta méthode equals:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    public boolean equals(Object o)
    {
           if(this==o) return true;
     
          //la suite
    }
    Dans la pratique, c'est très courant.

  9. #9
    Membre éprouvé
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    109
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 109
    Par défaut
    Citation Envoyé par @ldehan
    Une petite question concernant hashCode().


    quel est l'interet de redefinir hashCode(), pourquoi ne pas utliser celle de Object qui doit fonctionner tout le temps ?

    je n'ai pas tester et je n'ai jamais utiliser volontairement hashcode(), je ne l'ai d'ailleurs jamais redéfini... (c'est grave docteur ? ? ?)

    je pose la question parce qu'au programme des certifications java :
    hashCode() est utilisé par des algos dans certaines classes (HashSet, HashMap). si hashCode() est implémenté correctement, ça améliore les performances de ces classes.

    [edit]Et en effet, il y a des questions dessus lors de la certif.

    Au fait, dans vos exemples de equals, vous n'avez pas testé si le paramètre est null

  10. #10
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Salut,

    Citation Envoyé par @ldehan
    quel est l'interet de redefinir hashCode(), pourquoi ne pas utliser celle de Object qui doit fonctionner tout le temps ?
    La méthode hashCode() de Object n'est pas forcément la bonne, car elle considère que tous les objets sont différents, et le hashCode() renvoyé est donc toujours différents.

    Maintenant, il faut bien comprendre que l'objectif du hashCode est d'améliorer la recherche d'élément dans un arbre (c-a-d les différentes implémentations de Map). Pour simplifier (et parce que je ne connais pas le mechanisme en détail), lorsque tu ajoutes un couple clef/valeur dans une Map, le couple est stocké dans des tableaux internes selon le hashCode de la clef. Ainsi lorsque tu rechercheras la valeur associée à la clef, il accèdera uniquement à une partie des données (pas besoin de comparer toutes les clef de la Map).


    La méthode hashCode() doit normalement vérifier la condition suivante :
    Si deux objets sont egaux, alors leurs hashCode() sont également égaux (mais l'inverse n'est pas vrai).
    Et pour la classe Object, deux objet sont égaux uniquement si ils représentent la même instance. Par exemple le code suivant renvoit toujours false :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Object o1 = new Object();
    Object o2 = new Object();
    System.out.println( "equals() : " + o1.equals(o2) );
    System.out.println( "hashCode() : " + o1.hashcode() + ", " + o2.hashcode() );
    Tout simplement parce que la méthode equals() de Object est codé comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    public boolean equals(Object obj) {
        return (this == obj);
    }
    donc il n'y a pas de problème à renvoyer un hashCode différent...



    Or pour des objets un peu plus évolués, la méthode equals() se base sur le contenu de ces objets, et deux instances différents du même objet peuvent être égaux, par exemple si tu compares ces deux chaines tu obtiendras true et le même hashCode, ce qui est normal puisque bien qu'il s'agissent de deux instances différentes, elles représentent la même valeur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Object o1 = new String("hello");
    Object o2 = new String("hello");
    System.out.println( "equals() : " + o1.equals(o2) );
    System.out.println( "hashCode() : " + o1.hashcode() + ", " + o2.hashcode() );
    Tout simplement parce que la classe String a redéfini ces deux méthodes de manière concordante...


    Citation Envoyé par @ldehan
    je n'ai pas tester et je n'ai jamais utiliser volontairement hashcode(), je ne l'ai d'ailleurs jamais redéfini... (c'est grave docteur ? ? ?)
    Non... enfin ca dépend...

    Si tu n'utilises pas tes objets en tant que clef dans des Map, ce n'est pas vraiment utile (mais c'est toujours mieux de le faire).

    Sinon tu peux te retrouver avec des résultats incohérent et des éléments innaccessible dans tes Map...



    Généralement dans hashCode() je retourne la somme de tous les hashCode() des champs que j'utilise dans ma méthode equals(), ce qui donne quelque chose comme cela :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    public class MaClasse {
     
        private int field1;
        private String field2;
        private Date field3; // ignoré par equals() et hashcode()
     
     
        @Override
        public boolean equals(Object obj) {
            if (this==obj) {
                return true; // c'est la même instance
                // inutile de continuer c'est forcément égal !
            }        
            // on vérifie qu'il s'agissent bien de la même instance
            if (obj instanceof MaClasse) {
                MaClasse c = (MaClasse) obj;
     
     
                // on compare les différents champs :
                return 
                        // comparaison de type primaire :
                        (this.field1==c.field1) 
                    && ( 
                        // comparaison d'objet :
                        this.field2==c.field2 // comparaison de référence (au cas où)
                        || (this.field2!=null && this.field2.equals(c.field2)) // comparaison des objets
                    );
            }
            // sinon on retourne false;
            return false;
        }
     
        @Override
        public int hashCode() {
            return this.field1 + this.field2.hashCode();
        }
     
    }
    a++

  11. #11
    Membre expérimenté Avatar de @ldehan
    Profil pro
    Développeur Java
    Inscrit en
    Mars 2004
    Messages
    215
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2004
    Messages : 215
    Par défaut
    Merci d'avoir pris le temps de me repondre en détails, c'est déja beaucoup plus clair.

    mais j'aurais cependant une question quant à ton implémentation

    Citation Envoyé par adiGuba
    Généralement dans hashCode() je retourne la somme de tous les hashCode() des champs que j'utilise dans ma méthode equals()
    pourquoi ne pas utilisé le résultat de hashCode() de l'objet ? genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    super.hashCode() + this.field1 + this.field2.hashCode()

  12. #12
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par @ldehan
    pourquoi ne pas utilisé le résultat de hashCode() de l'objet ? genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    super.hashCode() + this.field1 + this.field2.hashCode()
    Parce que super.hashCode() appelle la méthode hashCode() de Object, qui renvoit une valeur différente pour chaque instance. Or si mes deux objets sont egaux hashCode() doit renvoyer la même valeur...

    a++

  13. #13
    Expert confirmé

    Avatar de denisC
    Profil pro
    Développeur Java
    Inscrit en
    Février 2005
    Messages
    4 050
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Service public

    Informations forums :
    Inscription : Février 2005
    Messages : 4 050
    Par défaut
    Citation Envoyé par adiGuba
    Généralement dans hashCode() je retourne la somme de tous les hashCode() des champs que j'utilise dans ma méthode equals(), ce qui donne quelque chose comme cela :
    Et si vous etes des flemmards comme moi (ou des gens qui cherchent à écrire le moins de code possible), c'est déjà tout fait dans commons-lang:
    http://jakarta.apache.org/commons/la...deBuilder.html

  14. #14
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par denisC
    Et si vous etes des flemmards comme moi (ou des gens qui cherchent à écrire le moins de code possible), c'est déjà tout fait dans commons-lang:
    http://jakarta.apache.org/commons/la...deBuilder.html
    Jakarta est vraiment formidable

  15. #15
    Membre expérimenté Avatar de @ldehan
    Profil pro
    Développeur Java
    Inscrit en
    Mars 2004
    Messages
    215
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2004
    Messages : 215
    Par défaut
    Citation Envoyé par adiGuba
    Parce que super.hashCode() appelle la méthode hashCode() de Object, qui renvoit une valeur différente pour chaque instance. Or si mes deux objets sont egaux hashCode() doit renvoyer la même valeur...

    a++
    Oui oui, autant pour moi. je viens de relire la javadoc avec les explications que tu m'as fourni. j'ai tout compris et j'y penserais dorénavent.

    Merci encore de toutes ces précisions

  16. #16
    Membre chevronné


    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    7 855
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 7 855
    Par défaut
    Citation Envoyé par Pollux
    Mais non il ne me semble pas. Si l'on surcharge la méthode equals il faut redéfinir également hashcode mais compareTo ce n'est pas du tout obligé! Cette méthode est définie lorsque la classe implémente Comparable mais autrement pas.
    Mea culpa pour la mauvaise compréhension de mon message.
    Je voulais simplement ajouter que de la définir pouvait s'avérer utile

    Eric

Discussions similaires

  1. Map et redéfinition du equals et hashCode
    Par jojodu31 dans le forum Collection et Stream
    Réponses: 18
    Dernier message: 02/12/2011, 15h33
  2. Redéfinition de equals
    Par robert_trudel dans le forum Débuter avec Java
    Réponses: 18
    Dernier message: 26/05/2008, 14h11
  3. redéfinition equals, hashmap et get
    Par oc_alex86 dans le forum Collection et Stream
    Réponses: 4
    Dernier message: 29/05/2007, 15h52
  4. [Héritage] Redéfinition méthode
    Par petit-ourson dans le forum Langage
    Réponses: 9
    Dernier message: 06/05/2004, 16h06
  5. [MFC] redéfinition de BEGIN_MESSAGE_MAP
    Par SethPech dans le forum C++Builder
    Réponses: 2
    Dernier message: 10/03/2004, 13h59

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo