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 :

[api] equals, compareTo


Sujet :

Langage Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Développeur informatique
    Inscrit en
    Mars 2005
    Messages
    110
    Détails du profil
    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mars 2005
    Messages : 110
    Par défaut [api] equals, compareTo
    Bonjour,
    J'ai une question au sujet de equals().
    J'ai une strukture de donnée qui implémente l'interface Comparable, par exemple une liste ou un arbre que j'implémente.(c'est un exercice :-) )
    J'ai une métode trouver(E obj) qui me renvoie un élément de la liste si celui-ci se trouve déjá dans la liste, null sinon.

    Nous travaillons avec des objets Mot (avec entre autre un attribut String leMot) Mon binôme a utilisé CompareTo pour trouver si le mot est déjà dans la structure, mais j'estime que c'est faux parce que CompareTo s'utlise pour ordonner des mots entre eux. Je pense que nous devons utiliser equals parce que le sens de equals est de savoir si les deux objets sont équivalents (et nous voulant avoir juste une instance de chaque mot dans la liste). Le resultats étant le même vu que les mots sont ordonnés alphabétiquement.

    Ma question est donc est il juste de dire que CompareTo et equals n'ont pas le même "sens"? De plus est-il juste d'implémenter une métode pour remplir un rôle, plutôt que juste pour obtenir un résultat (comme ici où equals et compareTo font la même chose, c'est à dire comparer "leMot")?

    Voilà en espérant avoir été clair, et que quelqu'un peut m'éclairer :-)

    --
    Dom

  2. #2
    Membre émérite Avatar de remika
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    806
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 806
    Par défaut
    equals appelle la méthode compareTo (il me semble)

    c'est donc à peu près la même chose pour tester une égalité

    ici equals est plus approprié à mon avis

  3. #3
    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,


    Tu peux très bien utiliser equals() pour rechercher un mot. Cela suffit amplement : equals() permet de vérifier l'égalité.

    Maintenant ce n'est pas faut non plus d'utiliser compareTo() pour cela, puisque ce dernier permet de comparer deux objets (il est donc plus complet car en plus de l'égalité il te donne des informations sur l'ordonnancement).


    Toutefois il est bien sûr préférable d'utiliser equals(), car son implémentation peut être plus performante que compareTo() puisqu'il effectue potentiellement moins d'opération.

    Exemple : si tu compares deux String différentes :
    • equals() parcourera les différents caractères et renverra false dès que deux caractères sont différents.
    • compareTo() devra te retourner une valeur correspond à l'ordonnancement de ces caractères. Et cela peut être un peu plus complexe selon le format de tes chaines et les règles que tu utilises, en particulier avec la classe Collator qui permet de gérer l'ordre des caractères du Français et non pas de l'ASCII (caractèrs accentué, etc.).



    Bien sûr dans tous les cas les méthodes equals() et compareTo() doit être concordante (si equals()==true alors compareTo()==0)

    a++

  4. #4
    Membre confirmé
    Développeur informatique
    Inscrit en
    Mars 2005
    Messages
    110
    Détails du profil
    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mars 2005
    Messages : 110
    Par défaut
    Wahoo ca c'est du rapide! :-)
    Merci de vos réponses et de la précision adiguba, j'´´etais pas au courant.

    Je ne crois pas que equals appelle compareTo, mais equals est plus lié au hashcode de l'object (qui devrait être overwrite pour etre consequent avec equals d'apres javadoc.equals)

    Dans le cas audessus, equals et compareTo font la même chose, mais je prenais l'exemple suivant pour argumenter avec mon cher camarade :-) :

    Si l'ordonnacement des mots se fait sur le nombre de lettre, alors compareTo() et equals() seront différent et on aurait "blabla".comparteTo("xxx")==0 mais on veut pas blabla.equals("xxx")=true. Donc je disais qu'il étais dangereux d'utiliser compareTo pour verifier si les deux mots sont équivalents (au cas où les exigences d'ordonnacement changent)

    Donc pour reformuler ma question plus précisement: est-ce une bonne pratique d'utiliser une métode d'après son sens, plutôt que d'après ce qu'elle renvoie?

    question bonus: dans une autre classe, j'ai CompareTo qui n'est pas conséquent avec equals (eaquals==true => compareTo==0 mais compareTo==0 !=> equals=true), est -ce un signe d'une faute de design ou bien cela est-il acceptable?

    Merci encore de vos réponse :-)

    --
    Dom

  5. #5
    Membre émérite Avatar de remika
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    806
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 806
    Par défaut
    (j'ai dit de la m.... dans mon dernier post)

    equals==true => compareTo==0 mais compareTo==0 !=> equals=true
    c'est pas forcément logique mais si ça te convient ya pas de problème

  6. #6
    Membre chevronné Avatar de gronono
    Inscrit en
    Novembre 2003
    Messages
    457
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Novembre 2003
    Messages : 457
    Par défaut
    Euh d'apres la javadoc :
    Citation Envoyé par javadoc compareTo()
    Returns a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object.
    Donc si compareTo donne 0 alors les objets sont égaux
    Donc equals donne true.

    Citation Envoyé par remika
    mais si ça te convient ya pas de problème
    comme le dis remika si ce ta convient alors c'est OK

    mais pour moi, il y a un probleme de logique (pense à celui va reprendre ton code à un jour peut-être)

  7. #7
    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 trolldom
    Je ne crois pas que equals appelle compareTo, mais equals est plus lié au hashcode de l'object (qui devrait être overwrite pour etre consequent avec equals d'apres javadoc.equals)
    C'est à toi d'implémenter les méthodes compareTo(), equals() et hashCode() selon les besoins et les caractéristiques de ton objet. Dans mon message je sous-entendais que toutes ces méthodes étaient correctement implémentée...

    Le seul lien entre equals() et hashCode() c'est que la règle suivante doit être respectée :
    • si a.equals(b) alors a.hashCode()==b.hashCode()
      (mais la réciproque n'est pas forcément vrai)


    Si tu veux vérifier l'égalité il y a des chances que equals() soit plus performant que compareTo(), car il fournit moins d'information sur l'inégalité (pas de notion d'ordonnancement). Si tu n'a pas besoin de cette information autant utilisé directement equals()...


    Citation Envoyé par remika
    equals==true => compareTo==0 mais compareTo==0 !=> equals=true
    Attention compareTo() et equals() doivent être cohérent :
    • si a.equals(b) alors a.compareTo(b)==0
      ET
      si a.compareTo(b)==0 alors a.equals(b)


    a++

  8. #8
    Membre émérite Avatar de remika
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    806
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 806
    Par défaut
    Attention compareTo() et equals() doivent être cohérent
    non pas forcément la javadoc elle-même le dit :

    It is strongly recommended, but not strictly required that (x.compareTo(y)==0) == (x.equals(y)). Generally speaking, any class that implements the Comparable interface and violates this condition should clearly indicate this fact. The recommended language is "Note: this class has a natural ordering that is inconsistent with equals."

  9. #9
    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
    En effet c'est vrai je me corrige :
    Attention compareTo() et equals() devrait généralement être cohérent
    J'ajouterais :
    • C'est quand même un cas particulier d'utilisation de compareTo() (dont j'ai un peu de mal à voir l'intérêt de la chose)...
    • Ca fait 1 points de plus pour l'utilisation d'equals()


    a++

  10. #10
    Membre Expert
    Avatar de Hephaistos007
    Profil pro
    Enseignant Chercheur
    Inscrit en
    Décembre 2004
    Messages
    2 493
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2004
    Messages : 2 493
    Par défaut
    It is strongly recommended, but not strictly required that (x.compareTo(y)==0) == (x.equals(y)). Generally speaking, any class that implements the Comparable interface and violates this condition should clearly indicate this fact. The recommended language is "Note: this class has a natural ordering that is inconsistent with equals."
    Il n'y a rien d'étonnant puisque compareTo() renseigne une relation d'ordre qui ne peut avoir que 3 significations :
    même ordre (au sens mathématique du terme, i.e même place)
    ordre inférieur
    ordre supérieur

    Les fonctions de tri de l'API s'appui sur cette fonction.

    equals teste l'égalité de 2 objets. On peut tout à fais avoir 2 objets que l'on considére de même ordre mais qui sont pourtant bien différents.
    Il est juste préférable, car plus intuitif, que 2 objets qui ont le même ordre implique que ces objets soit égaux. C'est à dire que tout objet unique ait un ordre unique. Faut voir si ce n'est pas lié aux relations d'ordre totale/partielle, avis aux matheux.
    Il vaut mieux mobiliser son intelligence sur des conneries que mobiliser sa connerie sur des choses intelligentes --- devise SHADOKS

    Kit de survie Android : mon guide pour apprendre à programmer sur Android, mon tutoriel sur les web services et enfin l'outil en ligne pour vous faire gagner du temps - N'oubliez pas de consulter la FAQ Android

  11. #11
    Membre confirmé
    Développeur informatique
    Inscrit en
    Mars 2005
    Messages
    110
    Détails du profil
    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mars 2005
    Messages : 110
    Par défaut
    pas completement simple

    Juste pour faire le point: j'estimais que pour tester l'égalité de 2 objets nous devions utilisé equals (au lieu de compareTo), justement pour éviter des problemes futurs si l'ordonancement des objets était modifié. Mais après dicussionj'avais fini par être incertain (merci pour les précisions)

    javadoc dit clairement que une classe devrait suivre:
    a.equals(b) => a.compareTo(b)==0

    mais je trouve javadoc peu clair sur la récirpoque.

    Hephaistos007 a écrit:
    Il est juste préférable, car plus intuitif, que 2 objets qui ont le même ordre implique que ces objets soit égaux

    mais il y a plein de cas ou il va etre naturel que a.compareTo(b)==0 ne dise rien sur l'égalité des objets(exemple une classe Golfeur qui est ordonnée suivant son Golfeur.handicap)

    Ce que je ne trouve pas clair dans javadoc, c'est si compareTo devrait être cohérent avec equals impliquait une relation dans les deux sens ou pas :-) (=> ou bien <=>)
    Je vois que adiGuba l'interpréte comme <=>, or pour moi compareTo() est un ordonnacement de différentes instances alors que equals teste l'égalité de 2 objets (ils représentent la même chose ou non)

    • À propos de hashcode:

    javadoc dit:
    As much as is reasonably practical, the hashCode method defined by class Object does return distinct integers for distinct objects.
    Donc il n'est pas impératif mais souhaitable que:
    hashCode(a)==hashCode(b) => a.equals(b)

    merci encore pour les précisions, a+

    --
    Dom

  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 trolldom
    mais il y a plein de cas ou il va etre naturel que a.compareTo(b)==0 ne dise rien sur l'égalité des objets(exemple une classe Golfeur qui est ordonnée suivant son Golfeur.handicap)
    Oui on peut en effet voir les choses comme cela... mais perso je préfère que dans ces cas là le compareTo()==0 ne soit renvoyé qu'après comparaison d'autre valeur (par exemple le nom du golpheur), afin d'être cohérent avec equals().


    Citation Envoyé par trolldom
    Je vois que adiGuba l'interpréte comme <=>, or pour moi compareTo() est un ordonnacement de différentes instances alors que equals teste l'égalité de 2 objets (ils représentent la même chose ou non)
    Pour moi s'il n'y a pas de différence (même niveaux d'ordonnancement) c'est qu'ils sont égaux (je parle bien de l'ordre naturel décrit par l'implémentation de Comparable et non pas d'autre ordonnement via des Comparator). Mais bien sûr on peut voir les choses différemment...



    Citation Envoyé par trolldom
    Donc il n'est pas impératif mais souhaitable que:
    hashCode(a)==hashCode(b) => a.equals(b)
    Mais ce n'est pas pour autant que cette relation est vrai :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Object o1 = "a";
    Object o2 = new Integer(97);
     
    System.out.println ( (o1==o2) ); // affiche true chez moi
    a++

  13. #13
    Membre confirmé
    Développeur informatique
    Inscrit en
    Mars 2005
    Messages
    110
    Détails du profil
    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mars 2005
    Messages : 110
    Par défaut
    Ok, je crois avoir maintenant vraiment saisi le point que compareTo==0 devrait conduire à equals=true.
    J'ai modifié ma classe qui était construite comme le "golfeur", cela me posait de toute facon des problèmes quand j'ai du mettre les objets dans un arbre de recherche binaire

    En résumé: compareTo() devrait être konséquente avec equals, c'est à dire:
    a.compareTo(b)==0 <=> a.equals(b)

    Dommage qu'il n'y est pas un bouton: Complétement résolu

    --
    Dom

  14. #14
    Membre Expert
    Avatar de Hephaistos007
    Profil pro
    Enseignant Chercheur
    Inscrit en
    Décembre 2004
    Messages
    2 493
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2004
    Messages : 2 493
    Par défaut
    Non, pas encore tout à fait résolu.

    javadoc dit clairement que une classe devrait suivre:
    a.equals(b) => a.compareTo(b)==0
    En fait c'est cette implication qui doit être respectée, l'implication inverse n'est pas forcément vraie, ce qui autorise sans problème l'exemple des golfeurs.
    En d'autres termes, ce que disent les gars de chez SUN c'est : si deux objets sont égaux alors logiquement il doivent avoir le même ordre car le contraire, c-a-d des objets égaux mais d'ordre différent, introduit selon moi de l'indéterminisme, concept jamais appréciable en informatique.

    D'ailleurs, on utilise le terme égaux et pas identiques. 2 objets totalement identiques sont obligés d'avoir le même ordre sinon il ya une couille dans le potage comme on dit. En revanche la méthode equalsTo est sujette aux choix de son concepteur : on peut considérer l'égalité que sur une partie des attributs par exemple.
    Il vaut mieux mobiliser son intelligence sur des conneries que mobiliser sa connerie sur des choses intelligentes --- devise SHADOKS

    Kit de survie Android : mon guide pour apprendre à programmer sur Android, mon tutoriel sur les web services et enfin l'outil en ligne pour vous faire gagner du temps - N'oubliez pas de consulter la FAQ Android

  15. #15
    Membre confirmé
    Développeur informatique
    Inscrit en
    Mars 2005
    Messages
    110
    Détails du profil
    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mars 2005
    Messages : 110
    Par défaut


    incroyable.. il est de plus en plus clair pour moi qu'il y a un petit coté obscure dans l'égalité mais en tous cas c'est un peu plus clair maintenant

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

Discussions similaires

  1. compareTo et equals Android
    Par makrane dans le forum Android
    Réponses: 8
    Dernier message: 13/06/2011, 17h17
  2. Difference entre compareTo et equals
    Par edogawa dans le forum Langage
    Réponses: 2
    Dernier message: 30/04/2007, 13h20
  3. Documentation gratuite sur l'API Windows, COM, DCOM, OLE, etc.
    Par Community Management dans le forum Windows
    Réponses: 1
    Dernier message: 16/11/2006, 15h28
  4. prob avec compareTo et equals..
    Par eureka dans le forum Langage
    Réponses: 1
    Dernier message: 27/03/2006, 09h08
  5. [java.lang] Object/String --> compareTo() ou equals()
    Par wdionysos dans le forum Langage
    Réponses: 17
    Dernier message: 17/01/2006, 23h41

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