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

avec Java Discussion :

la méthode equals()


Sujet :

avec Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre Expert
    Avatar de slim_java
    Homme Profil pro
    Enseignant
    Inscrit en
    Septembre 2008
    Messages
    2 272
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Tunisie

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2008
    Messages : 2 272
    Par défaut la méthode equals()
    salut tout le monde .je veut vérifier avec vous le fonctionnement de la mtéhode equals()
    ce que je savais ,c'est que equals() teste si deux objets admettent les méme valeus au niveau des attributs.
    voila mon cas de figure:
    j'ai deux objets de classe B qui héritent de la classe A en ajoutant d'autre attributs.
    je veut vérifier si c'est deux objets sont égaux en tant que objet de la classe A ,c'est a dire je veut vérifier s'il possède les même valeurs UNIQUEMENT au niveau des attributs de la classe A ?
    alors dans ce cas ,je peut me servir de mon equals() ou il ya d'autre solution ?

  2. #2
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    104
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Mars 2004
    Messages : 104
    Par défaut
    Salut,

    la méthode equals est faite pour ça mais c'est à toi de coder comment tu fais la comparaison entre 2 objets (quelles sont les propriétés de ton objet à comparer).
    Tu peux avoir redéfinit une méthode equals pour ta classe A et avoir une définition plus complète pour ta classe B.
    Regarde bien la javadoc de cette méthode, il y a un certain contrat à respecter.
    De plus quand on redéfinit la méthode equals, il est fortement recommandé de redéfinir aussi la méthode hashCode

  3. #3
    Membre Expert
    Avatar de slim_java
    Homme Profil pro
    Enseignant
    Inscrit en
    Septembre 2008
    Messages
    2 272
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Tunisie

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2008
    Messages : 2 272
    Par défaut
    Citation Envoyé par Kirua12 Voir le message
    Salut,

    la méthode equals est faite pour ça mais c'est à toi de coder comment tu fais la comparaison entre 2 objets (quelles sont les propriétés de ton objet à comparer).
    Tu peux avoir redéfinit une méthode equals pour ta classe A et avoir une définition plus complète pour ta classe B.
    Regarde bien la javadoc de cette méthode, il y a un certain contrat à respecter.
    De plus quand on redéfinit la méthode equals, il est fortement recommandé de redéfinir aussi la méthode hashCode
    bon pour mon cas de figure ça a bien fonctionner mais il faut coméme jetez un cou d'œil sur
    Regarde bien la javadoc de cette méthode

  4. #4
    Membre Expert
    Avatar de professeur shadoko
    Homme Profil pro
    retraité nostalgique Java SE
    Inscrit en
    Juillet 2006
    Messages
    1 257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 76
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : retraité nostalgique Java SE

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 257
    Par défaut
    donc dans ton cas on pourra comparer un objet de classe A avec un objet de classe B.
    moi je suis plutot pour (pour des tas de raisons) ...
    et donc je m'étonne d'un comportement par défaut d'Eclipse qui génère une comparaison avec getClass() (on peut heureusement modifier ça ouf..) .... pour moi ce comportement par défaut frise l'hérésie.
    qu'en pense la communauté?

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

    Informations forums :
    Inscription : Novembre 2005
    Messages : 1 312
    Par défaut
    Citation Envoyé par professeur shadoko Voir le message
    et donc je m'étonne d'un comportement par défaut d'Eclipse qui génère une comparaison avec getClass() (on peut heureusement modifier ça ouf..) .... pour moi ce comportement par défaut frise l'hérésie.
    qu'en pense la communauté?
    Ben en fait, en faisant ça, tu risques de briser l'une des conditions définie par le contrat allant avec la méthode equals, à savoir la symétrie.

    Pour rappel, voici le contrat de la méthode equals :

    Citation Envoyé par Javadoc
    ndicates whether some other object is "equal to" this one.

    The equals method implements an equivalence relation on non-null object references:

    * It is reflexive: for any non-null reference value x, x.equals(x) should return true.
    * It is symmetric: for any non-null reference values x and y, x.equals(y) should return true if and only if y.equals(x) returns true.
    * It is transitive: for any non-null reference values x, y, and z, if x.equals(y) returns true and y.equals(z) returns true, then x.equals(z) should return true.
    * It is consistent: for any non-null reference values x and y, multiple invocations of x.equals(y) consistently return true or consistently return false, provided no information used in equals comparisons on the objects is modified.
    * For any non-null reference value x, x.equals(null) should return false.

    La règle de symétrie dit que pour tout objet x et y non null, si x.equals(y) renvoie true alors y.equals(x) doit aussi renvoyer true.

    En introduisant une comparaison avec la classe A dans la méthode equals de B tu peux enfreindre cette règle car la méthode equals de l'objet A ne connait rien de B et par conséquent B.equals(A) pourra renvoyer un résultat différent de A.equals(B).

    C'est pour respecter cette règle de symétrie qu'Eclise introduit des getClass() dans les méthodes equals qu'il génère.

  6. #6
    Membre Expert
    Avatar de professeur shadoko
    Homme Profil pro
    retraité nostalgique Java SE
    Inscrit en
    Juillet 2006
    Messages
    1 257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 76
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : retraité nostalgique Java SE

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 257
    Par défaut
    Citation Envoyé par Deadpool Voir le message
    Ben en fait, en faisant ça, tu risques de briser l'une des conditions définie par le contrat allant avec la méthode equals, à savoir la symétrie.

    Pour rappel, voici le contrat de la méthode equals :




    La règle de symétrie dit que pour tout objet x et y non null, si x.equals(y) renvoie true alors y.equals(x) doit aussi renvoyer true.

    En introduisant une comparaison avec la classe A dans la méthode equals de B tu peux enfreindre cette règle car la méthode equals de l'objet A ne connait rien de B et par conséquent B.equals(A) pourra renvoyer un résultat différent de A.equals(B).

    C'est pour respecter cette règle de symétrie qu'Eclise introduit des getClass() dans les méthodes equals qu'il génère.
    j'ai plusieurs raisons de contester cette interprétation:

    deux cas :

    - si equals exprime l'identité d'un objet (une clef ou un ensemble de clefs) il n'y a pas de raison de modifier le test dans une sous-classe
    utiliser getClass() est une erreur pour deux raisons:
    * si le même objet est chargé par deux ClassLoaders différents ça rend faux
    (et c'est p.e. pour ça que tu cherches à tester l'identité)
    * l'identité peut être simulée par un Proxy et là tu es coincé
    exemple: tu compares un CompteEnBanque (type interface) dont le type
    effectif est CompteBleu avec un autre CompteEnBanque dont le type effectif est une référence distante vers un CompteEnBanque sur le réseau. Si equals dans CompteBleu utilise getClass() t'es mal ....


    - si equals exprime un égalité de contenu (un Point, une ArrayList, etc.)
    si jamais ta sous-classe modifie le contrat de equals les codes doivent s'écrire un peu de cette manière :
    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
     
    // dans super classe
    public boolean equals(Object autre) {
       // test bateaux du genre if (this == autre)
       return (autre instanceof MaClasse) &&
         (((MaClasse)autre).contenu.equals(this.contenu)) ;
          // note inverser le test si risque de contenu null !!
    }
     
    // dans sous-classe
    public boolean equals(Object autre) {
       if(autre instanceof SousClasse) {
          return super.equals(autre) && 
            (((SousClass)autre).supplements.equals(this.supplements)) ;
     
       }
       return super.equals(autrre);
    }
    bien entendu on peut faire mieux avec des instanceof d'une interface etc.
    ici toutes les règles du contrat de equals sont respectées.
    (et si on regarde les codes standard de Java c'est dans ce style que c'est écrit -il y a extrèmement peu d'utilisation de getClass() sauf dans les codes Taligent de java.text-).
    exemple: du point de vue de Point equals va rendre ok avec un PointColore de même coordonées... ça peut sembler très zarbi mais tu rends la sémantique
    de equals de Point quand tu compares avec la super-classe. Bien entendu on peut contester cette égalité avec un code approprié si nécessaire.

    Autre raison de rejeter getClass() dans la majorité des cas: tu as toutes les chances de créer un objet Comparable dans lequel les comparaisons sont incompatibles avec equals (voir doc de Comparable et Comparator). -c'est pas interdit mais alors prudence!
    exemple: si dans PointColoré tu contestes le equals de Point tu ne peux plus comparer correctement des Points dans un tableau.

  7. #7
    Membre expérimenté Avatar de Torg666
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2008
    Messages
    230
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2008
    Messages : 230
    Par défaut
    Citation Envoyé par professeur shadoko Voir le message
    donc dans ton cas on pourra comparer un objet de classe A avec un objet de classe B.
    moi je suis plutot pour (pour des tas de raisons) ...
    et donc je m'étonne d'un comportement par défaut d'Eclipse qui génère une comparaison avec getClass() (on peut heureusement modifier ça ouf..) .... pour moi ce comportement par défaut frise l'hérésie.
    qu'en pense la communauté?
    L'hérésie c'est de surcharger la méthode equals pour faire quelquechose qui n'a rien avoir avec equals. Comme dis plus haut, equals doit respecter la symetrie. Si tu tiens a faire ca, fait une méthode avec un autre nom, ca a le mérite de lever toute ambiguité.

    Perso, si je vois ca dans du code... je traque le développeur qui a pondu ça, et je le fais bouillir à petit feu dans une tasse à cafe!

  8. #8
    Membre Expert
    Avatar de professeur shadoko
    Homme Profil pro
    retraité nostalgique Java SE
    Inscrit en
    Juillet 2006
    Messages
    1 257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 76
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : retraité nostalgique Java SE

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 257
    Par défaut
    Citation Envoyé par Torg666 Voir le message
    L'hérésie c'est de surcharger la méthode equals pour faire quelquechose qui n'a rien avoir avec equals.
    ça serait super.... mais la sémantique de equals est elle même ambigue: identité ou contenu?
    on voit bien qu'il y a de nombreux cafouillages: si un descendant d'AbstractList se retrouve dans un Set il va falloir se poser des questions: de quoi parle-t'on?

    <détournement>
    pour les hérétiques deux punitions sont possibles:
    - les faire frire dans du jus de poivre rouge bouillant (ça c'est la version de Foufi pour les connaisseurs)
    - les décapiter et ensuite les pendre (version des Hackers)
    </détournement>

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Modifier la méthode equals() générée par eclipse
    Par Faiche dans le forum Eclipse Java
    Réponses: 2
    Dernier message: 15/09/2009, 08h57
  2. méthode equals() explications
    Par kimlaw95 dans le forum Débuter avec Java
    Réponses: 3
    Dernier message: 11/05/2009, 17h21
  3. Méthode "equals" dans une liste.
    Par c-ve dans le forum Langage
    Réponses: 5
    Dernier message: 04/03/2009, 14h39
  4. Réponses: 0
    Dernier message: 26/11/2007, 15h47
  5. La méthode equals() de la classe String
    Par Nayila dans le forum Langage
    Réponses: 5
    Dernier message: 31/10/2007, 13h09

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