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 :

[java.lang] Object/String --> compareTo() ou equals()


Sujet :

Langage Java

  1. #1
    Membre habitué Avatar de wdionysos
    Profil pro
    Consultant informatique
    Inscrit en
    Novembre 2003
    Messages
    222
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : Luxembourg

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Novembre 2003
    Messages : 222
    Points : 189
    Points
    189
    Par défaut [java.lang] Object/String --> compareTo() ou equals()
    bonjour,

    je voudrais simplement savoir quelle methode faut t-il employe pour comparer deux objets String equals() ou compareTo()

    je precise que j'ai besoin de comparer la valeur exact de mon objet et j'ai l'impression que equals ne compare que les adresses memoire des objets et non leur contenu.

    La question prevaut egalement pour un objet de la classe Timestamp ?

    Cas general
    si j'ai un objet (javabean) construit avec plx String comme proprietes et que je souhaite pouvoir voir l'egalite, pour savoir si le contenu de mon objet est strictement identique a l'objet passe en parametre. puis je utiliser directement la methode equals ou compareTo de la classe object ou dois je redefinir une methode qui compare propriete par propriete

    ???


    merci

    WD[/b]

  2. #2
    Membre habitué
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    151
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 151
    Points : 144
    Points
    144
    Par défaut
    Si tu ne surcharges pas la méthode equals alors elle se base sur la référence de ton objet sinon c'est à toi de le définir ( c'est toujours mieux je pense pour les objets métiers du moins).

    Ensuite si c'est juste pour savoir si 2 objets sont égaux ou non il vaut mieux surcharger la méthode equals que compareTo car la méthode equals est utilisé un peu partout dans l'api standard ( ce qui est très agréable d'ailleurs).

    Par exemple si tu veux savoir si ton objet est contenu dans une liste tu utilises: Là c'est la méthode equals qui est appellé. Cette méthode peut très bien renvoyer un résultat cohérent dans le cas où tu testes l'existence dans la liste avec l'objet qui est contenu dedans ( donc avec la même référence) mais je pense que c'est toujours mieux d'avoir définit son propre equals.

    La méthode compareTo est surtout utile si tu as besoin de mettre une relation d'ordre dans tes objets ( objet1>objet2 si et seulement si .... )

  3. #3
    Expert éminent sénior
    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
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut Re: [java.lang] Classe String --> compareTo() ou equals(
    Salut,

    Citation Envoyé par wdionysos
    je voudrais simplement savoir quelle methode faut t-il employe pour comparer deux objets String equals() ou compareTo()
    Les deux peuvent faire l'affaire... compareTo() te donnant en plus une information sur l'ordre des chaines...


    Citation Envoyé par wdionysos
    je precise que j'ai besoin de comparer la valeur exact de mon objet et j'ai l'impression que equals ne compare que les adresses memoire des objets et non leur contenu.
    En fait cela dépend : la méthode equals() hérité de Object se contente de comparer les références des objets (donc a.equals(b) ssi a==b).
    Pourquoi : simplement parce qu'un Object n'a pas de contenu particulier.

    Il faut donc que les différentes classes redéfinissent leurs propre méthodes equals() pour y ajouter leur propre code métier...


    Citation Envoyé par wdionysos
    La question prevaut egalement pour un objet de la classe Timestamp ?
    Il suffit de regarder dans l'API pour voir que Timestamp.equals() est bien redéfini...

    Citation Envoyé par wdionysos
    Cas general
    si j'ai un objet (javabean) construit avec plx String comme proprietes et que je souhaite pouvoir voir l'egalite, pour savoir si le contenu de mon objet est strictement identique a l'objet passe en parametre. puis je utiliser directement la methode equals ou compareTo de la classe object ou dois je redefinir une methode qui compare propriete par propriete
    Tu dois redéfinir la méthode equals(Object) en lui ajoutant le code métier qui permet de comparer tes objets, par exemple pour une classe contenant deux champs, cela pourrait ressembler à :

    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
    public class MaClasse {
     
    	private String name;
    	private String value;
     
     
    	public boolean equals(Object otherObject) {
     
    		boolean result = false;
     
    		if (this==otherObject) {
    			// même référence donc egal !
    			result = true; 
    		} else if (otherObject instanceof MaClasse) {
    			MaClasse other = (MaClasse) otherObject;
     
    			result = this.name.equals(other.name) &&
    				this.value.equals(other.value);
     
    		}
    		return result;
    	}
     
    }
    De plus si tu dois utiliser ton objet en tant que clef d'une Map, il faut aussi redéfinir la méthode hashCode()...

    a++

  4. #4
    Membre habitué
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    151
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 151
    Points : 144
    Points
    144
    Par défaut
    es deux peuvent faire l'affaire... compareTo() te donnant en plus une information sur l'ordre des chaines...
    Les deux peuvent faire l'affaire mais si il veut utiliser les méthodes qui testent l'existence (celles de l'api) c'est surtout la méthode equals qui est appellée. Ce qui est très utile quand on manipule des objets dont on est pas sur que la "bonne" réfèrence est utilisé ( le cas de la pluspart des applis distribués )

  5. #5
    Membre habitué Avatar de wdionysos
    Profil pro
    Consultant informatique
    Inscrit en
    Novembre 2003
    Messages
    222
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : Luxembourg

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Novembre 2003
    Messages : 222
    Points : 189
    Points
    189
    Par défaut
    Eh bien , rien a redire , tout est la,

    merci a vous deux.

    pour le contexte ce n'est pas dans une liste ou une map mais dans une collection en provenance d'un DAO attaquant une base. je construit des objet globaux travaillant sur plx tables donc j'ai besoin de savoir avant de saisir par ex un nouveau pays si celui ci n'a pas deja ete defini (cad meme nom, meme drapeau, meme description, meme id etc...)

    j'avais deja pris les devant en redefinissant equals comme ceci (javabean client)
    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
     
    		public Boolean equals(ClientInfo anotherclient){
    			boolean bool = false;
       		        if (this.idclient  == anotherclient.idclient               	              &&
    				this.idsale    == anotherclient.idsale                               &&
    				this.idcountry == anotherclient.idcountry                      &&
    				this.iddomain  == anotherclient.iddomain                       &&
    				this.idgroupe  == anotherclient.idgroupe                        &&
    				this.nameclient.equals(anotherclient.nameclient)           &&
    				this.adressclient.equals(anotherclient.adressclient)       &&
    				this.zipcodeclient.equals(anotherclient.zipcodeclient)     &&
    				this.postalboxclient.equals(anotherclient.postalboxclient) &&
    				this.cityclient.equals(anotherclient.cityclient)           &&
    				this.telclient.equals(anotherclient.telclient)             &&
    			        this.faxclient.equals(anotherclient.faxclient)             &&
    				this.logoclient.equals(anotherclient.logoclient)           &&
    				this.videoclient.equals(anotherclient.videoclient)         &&
    				this.website.equals(anotherclient.website)                 &&
    				this.credateclient.equals(anotherclient.credateclient)
    				){
    					bool = true;
    			}
    			return new Boolean(bool);
    		}
    mais la j'ai un Null pointer object ???


    why ?

    WD

  6. #6
    Membre habitué Avatar de wdionysos
    Profil pro
    Consultant informatique
    Inscrit en
    Novembre 2003
    Messages
    222
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : Luxembourg

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Novembre 2003
    Messages : 222
    Points : 189
    Points
    189
    Par défaut
    bon le null pointer exception c'est parce la propriete postalbox est null dans les deux objet que je compare, moi je souhaiterai que la condition renvoie true meme si les deux propriete (ici postalbox dans chaque objet) sont a null.

  7. #7
    Expert éminent sénior
    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
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par wdionysos
    bon le null pointer exception c'est parce la propriete postalbox est null dans les deux objet que je compare, moi je souhaiterai que la condition renvoie true meme si les deux propriete (ici postalbox dans chaque objet) sont a null.
    Tu dois traiter explicitement les cas null...


    Sinon attention car ta méthode ne redéfinit pas la méthode equals() de la classe Object, ce qui pourrait induire en erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     public Boolean equals(ClientInfo anotherclient)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     public boolean equals(Object anotherclient)
    a++

  8. #8
    Membre habitué Avatar de wdionysos
    Profil pro
    Consultant informatique
    Inscrit en
    Novembre 2003
    Messages
    222
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : Luxembourg

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Novembre 2003
    Messages : 222
    Points : 189
    Points
    189
    Par défaut
    yo

    Citation Envoyé par adiGuba
    public boolean equals(Object anotherclient)
    ah bon ! qu'est ce que cela va changer car ClientInfo est un Object, particulier certe, mais la methode ne sera appelle que sur un objet client puisque ce DAO ne travaille que sur la table client de la DB.

    ce dont j'ai besoin c'est d'une methode pour chaque objet de mon dao capable de me dire s'il est egal a un autre objet du meme type de la meme maniere que j'ai defini pour chaque objet une foinction copy() qui copie l'objet implicite sur lequel elle est appele.

    WD[/quote]

  9. #9
    Membre habitué Avatar de wdionysos
    Profil pro
    Consultant informatique
    Inscrit en
    Novembre 2003
    Messages
    222
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : Luxembourg

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Novembre 2003
    Messages : 222
    Points : 189
    Points
    189
    Par défaut
    sinon puis je me contenter simplement d'une methode qui compare les adresse de reference memoire des objet selon l'adage que :

    si la reference est identique alors l'objet (les proprietes de l'objet) le sont aussi

    est ce suffisant au niveau de la securite\

    WD

  10. #10
    Expert éminent sénior
    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
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par wdionysos
    yo

    Citation Envoyé par adiGuba
    public boolean equals(Object anotherclient)
    ah bon ! qu'est ce que cela va changer car ClientInfo est un Object, particulier certe, mais la methode ne sera appelle que sur un objet client puisque ce DAO ne travaille que sur la table client de la DB.
    Cela ne change rien lorsque tu appelles explicitement ta méthode plutôt que celle hérité de Object... Mais dans de nombreux cas c'est cette dernière qui est utilisé, comme par exemple par la méthode contains() des Collections, etc... Ce qui fait que tu risques de te retrouver avec des appels de equals(Object) en croyant que c'est equals(ClientInfo) qui est utilisé, et donc tu risque d'obtenir des résultats apparemment incohérents...

    A la rigueur tu peux simplement appeller la méthode equals(ClientInfo) dans equals(Object) si le type concorde :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public boolean equals(Object object) {
    	if (object instanceof ClientInfo) {
    		return equals( (ClientInfo)object );
    	}
    	return false;
    }
     
    public boolean equals(ClientInfo otherClient) {
    	// ...
    }


    Citation Envoyé par wdionysos
    ce dont j'ai besoin c'est d'une methode pour chaque objet de mon dao capable de me dire s'il est egal a un autre objet du meme type de la meme maniere que j'ai defini pour chaque objet une foinction copy() qui copie l'objet implicite sur lequel elle est appele.
    N'importe quel méthode que tu implémente correctement pourrais faire l'affaire, mais equals(Object) est prévu pour cela et elle a l'avantage de pouvoir être utilisé par d'autre classe/API...

    a++

  11. #11
    Membre habitué Avatar de wdionysos
    Profil pro
    Consultant informatique
    Inscrit en
    Novembre 2003
    Messages
    222
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : Luxembourg

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Novembre 2003
    Messages : 222
    Points : 189
    Points
    189
    Par défaut
    eh bien j'en sais assez , merci a vous deux

    special Adi merci pour le dernier code d'appel entre object et Clientinfo, simple mais il fallait u penser

    un petit resolu et y'a plus qu'A !

    bonne fin de journee

    WDionysos

  12. #12
    Expert éminent sénior
    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
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par wdionysos
    sinon puis je me contenter simplement d'une methode qui compare les adresse de reference memoire des objet selon l'adage que :

    si la reference est identique alors l'objet (les proprietes de l'objet) le sont aussi
    Si la référence est identique c'est le même objet donc les mêmes propriétées donc c'est forcément identique...

    Par contre l'inverse n'est pas vrai !!! Deux instances de l'objet ont forcément une référence différente malgré le fait qu'il peuvent avoir des propriétées identiques (et sont donc identiques selon ton code métier).

    a++

  13. #13
    Membre habitué Avatar de wdionysos
    Profil pro
    Consultant informatique
    Inscrit en
    Novembre 2003
    Messages
    222
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : Luxembourg

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Novembre 2003
    Messages : 222
    Points : 189
    Points
    189
    Par défaut
    une derniere remarque pour la perenite de l'info

    ta methode de redefinition de object.equals(object) qui renvoie sur ClientInfo.equals(ClientInfo) est tres bonne mais elle interdit l'utilisation de Wrapper de type Boolean.

    Sachant que mes consigne sont 100% objet dc pas de type simple en dehors des fonction locale, ca colle pas a mon cas car le type de retout de object.equals(object) conditionne le type de retour de ClientInfo.equals(ClientInfo) a savoir boolean.

    sinon on obtient un "convert type mismatch"

    ps : qui a dit que JRE Tigger wrappait desormais implicitement les type simple emn objet et vice versa ???

    WDIO

  14. #14
    Expert éminent sénior
    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
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par wdionysos
    sinon on obtient un "convert type mismatch"

    ps : qui a dit que JRE Tigger wrappait desormais implicitement les type simple emn objet et vice versa ???
    Tu es sûr que tu compile bien ton code en Java 5.0 ? (certain EDI reste encore en 1.4).

    Sinon rien ne t'empêche de la faire toi même :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    public boolean equals(Object object) {
       if (object instanceof ClientInfo) {
          return equals( (ClientInfo)object ).booleanValue();
       }
       return false;
    }
    a++

  15. #15
    Membre habitué Avatar de wdionysos
    Profil pro
    Consultant informatique
    Inscrit en
    Novembre 2003
    Messages
    222
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : Luxembourg

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Novembre 2003
    Messages : 222
    Points : 189
    Points
    189
    Par défaut
    exact Adi, j'en etait arrive a la meme conclusion

    merci bcp

    pour la betise que je viens de dire, si qq'1 passe par la qu'il sache que la conversion implicite (que j'ai testé) avec Java 1.5 fonctionne bien

    par exemple, si on utilise une fonction native java qui a besoin d'un objet integer en param, on peut ecrire
    , et Tiger va le convertir automatiquement en
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    argimp.fonction(new Integer(i))
    Trop tard pour moi car depuis le debut de mon prog j'ai systematiquement utilise des wrappers, dc je me suis complique la vie c'est vrai....

    ah les vieilles habitudes :

    et c'est mon dernier mot, jean pierre !

  16. #16
    Membre habitué Avatar de wdionysos
    Profil pro
    Consultant informatique
    Inscrit en
    Novembre 2003
    Messages
    222
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : Luxembourg

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Novembre 2003
    Messages : 222
    Points : 189
    Points
    189
    Par défaut
    apres celui ci

    je suis certain que j'ai une java 5.0 mais dans eclipse a cote j'ai aussi un J2EE SDK 1.4 je teste alternativement mes classe avec l'une ou l'autre et j'avoue quand j'ai compile j'etait en 1.4 donc je n'ai pas respecter l'adage qui dit qu'il faut toujours compiler sept fois son prog avant de poster

    WDIO

  17. #17
    Expert éminent sénior
    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
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par wdionysos
    par exemple, si on utilise une fonction native java qui a besoin d'un objet integer en param, on peut ecrire
    , et Tiger va le convertir automatiquement en
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    argimp.fonction(new Integer(i))
    Juste un détail : en réalité le code est équivalent à :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    argimp.fonction(Integer.valueOf(i))
    Qui a l'avantage de gérer un cache et permet ainsi d'éviter quelques instantiations d'objets (cf Integer.valueOf(int)).

    Mais de toute manière si tu dois rendre ton code compatible avec Java 1.4.2 tu ne peux pas l'utiliser...

    a++

  18. #18
    Membre habitué Avatar de wdionysos
    Profil pro
    Consultant informatique
    Inscrit en
    Novembre 2003
    Messages
    222
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : Luxembourg

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Novembre 2003
    Messages : 222
    Points : 189
    Points
    189
    Par défaut
    Ok je ne savait pas pour valueOf je vais m'empresser de lire la doc,

    sinon oui l'avantage de rester compatible avec des version anterieures est important et par ailleurs la fainéantise de refactorer tout mon code pour passer des Integer en int , des Bolleans en booleans ... non non c'est aussi de mes moyens

    Et comme ca ca a l'avantage d'avoir été validé par dieu en personne (Sun).

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

Discussions similaires

  1. java.lang.Object javax.media.Buffer.getData()
    Par keil dans le forum Multimédia
    Réponses: 3
    Dernier message: 28/07/2011, 13h41
  2. Javadoc sur classes n'héritant pas de java.lang.Object
    Par superpoupou dans le forum EDI et Outils pour Java
    Réponses: 2
    Dernier message: 30/05/2008, 17h41
  3. java.lang.object cannot be resolved
    Par hammag dans le forum Servlets/JSP
    Réponses: 9
    Dernier message: 24/06/2007, 11h32
  4. Réponses: 2
    Dernier message: 02/01/2007, 11h19
  5. [Débutant] java.lang.object
    Par bonnefr dans le forum Eclipse Java
    Réponses: 1
    Dernier message: 27/05/2004, 14h54

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