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

Eclipse Java Discussion :

Mon("equal") != Eclipse("equa"l)


Sujet :

Eclipse Java

  1. #1
    Membre éclairé

    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Septembre 2007
    Messages
    214
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Santé

    Informations forums :
    Inscription : Septembre 2007
    Messages : 214
    Points : 816
    Points
    816
    Par défaut Mon("equal") != Eclipse("equa"l)
    Bonjour,

    J’ai une classe "Ville". J’ai défini à la main moi-même tout seul la méthode "equal". Voila le résultat :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    public boolean equal(Ville o) {
    	if(this.nomVille!=o.nomVille) return false;
    	if(this.nbHabitants!=o.nbHabitants) return false;
    	if(this.nomPays!=o.nomPays) return false;
    	return true;
    }
    J’ai ensuite demandé à Eclipse de définir la méthode automatiquement. Voilà le résultat :
    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
    public boolean equals(Object obj) {
    	if (this == obj) return true;
    	if (obj == null) return false;
    	if (getClass() != obj.getClass()) return false;
     
    	Ville other = (Ville) obj;
    	if (nbHabitants != other.nbHabitants) return false;
    	if (nomPays == null) {
    		if (other.nomPays != null) return false;
    	} else {
                    if (!nomPays.equals(other.nomPays)) return false;
    	}
    	if (nomVille == null) {
    		if (other.nomVille != null) return false;
    	} else {
                    if (!nomVille.equals(other.nomVille)) return false;
    	}
    	return true;
    }
    J’ai un peu du mal à comprendre...

    Ligne 3 : obj==null : pourquoi retourner false ? Si mon objet this est null, et que obj est null, alors je devrais retourner true, non ?

    Christophe
    Christophe
    Porteur du projet R++ https://rplusplus.com
    YouTubeur https://www.youtube.com/c/lesstatsmemepasmal

  2. #2
    Membre éprouvé
    Inscrit en
    Mars 2006
    Messages
    848
    Détails du profil
    Informations personnelles :
    Âge : 40

    Informations forums :
    Inscription : Mars 2006
    Messages : 848
    Points : 1 078
    Points
    1 078
    Par défaut
    Bonjour,

    this n'est jamais null, il s'agit de l'objet qui "exécute" la méthode.

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juillet 2013
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2013
    Messages : 7
    Points : 27
    Points
    27
    Par défaut
    En gros si tu fais ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Ville ville1 = null;
    Ville ville2 = null;
    if (ville1.equals(ville2)) {
      // Do something
    }
    Tu vas avoir un NullPointerException car ville1 n'est pas initialisé et il te sera impossible d’appeler une méthode de Ville.
    Notes aussi que ta méthode générée s'appelle "equals" et non "equal". Prends l'habitude de nommer ce genre de méthode ainsi car certaines classe utilise les méthodes "equals" de tes objets pour les trier par exemple.
    Avec un paramètre de type Object et un petit @Override au dessus de la méthode :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    @Override
    public boolean equals(Object o) {
      boolean result = false;
      // Do something
      return result;
    }

  4. #4
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 547
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 547
    Points : 21 602
    Points
    21 602
    Par défaut
    Détail amusant :

    this n'est pas null, on le sait, d'accord.
    Mais s'il l'était, et que obj est null aussi, ce serait géré en ligne 2, qui renverrait true .
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  5. #5
    Membre éclairé

    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Septembre 2007
    Messages
    214
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Santé

    Informations forums :
    Inscription : Septembre 2007
    Messages : 214
    Points : 816
    Points
    816
    Par défaut
    Donc, en supposant que je fais a1.equal(a2) :

    • this n'est jamais null
    • Si a1 est null, il ne peut pas appeler equal et ca lève une exception.
    • Si a1 n'est pas null mais que a2 est null, alors il faut retourner false, ce qui est fait ligne 3
    • Au passage, je comprends (grâce au post "valueOf(j).intValue() ou valueOf(j) ?") maintenant la ligne 2 : si a1 et a2 pointent sur la même chose, alors equal retourne true sans se soucier du reste.

    C'est ca ?

    Christophe
    Christophe
    Porteur du projet R++ https://rplusplus.com
    YouTubeur https://www.youtube.com/c/lesstatsmemepasmal

  6. #6
    Membre habitué
    Homme Profil pro
    Chef de projet, développeur .net
    Inscrit en
    Juin 2010
    Messages
    76
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Chef de projet, développeur .net
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2010
    Messages : 76
    Points : 136
    Points
    136
    Par défaut
    Oui, a la ligne 2 ou test les pointeurs. S'ils sont égaux, ils référencent la même instance, donc on renvoie true.

  7. #7
    Membre expert
    Avatar de aityahia
    Homme Profil pro
    CIEPTAL CARS SPA
    Inscrit en
    Mars 2006
    Messages
    1 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Algérie

    Informations professionnelles :
    Activité : CIEPTAL CARS SPA
    Secteur : Transports

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 938
    Points : 3 329
    Points
    3 329
    Par défaut
    salut,

    j'ais juste une petite remarque au passage, généralement quand je redéfinis la méthode equal de mes Objets, j'utilise la méthode equalsIgnoreCase pour les attributs de type String dans le cas ou la casse n'est pas prise en compte.

    Code java : Sélectionner tout - Visualiser dans une fenêtre à part
    this.nomVille().equalsIgnoreCase(obj.nomVille)

    sinon je vois pas l’intérêt de la redéfinir

  8. #8
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 547
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 547
    Points : 21 602
    Points
    21 602
    Par défaut
    Citation Envoyé par aityahia Voir le message
    j'ais juste une petite remarque au passage, généralement quand je redéfinis la méthode equal de mes Objets, j'utilise la méthode equalsIgnoreCase pour les attributs de type String dans le cas ou la casse n'est pas prise en compte.
    Pas moi. Le hashCode(), si la classe est censée pouvoir s'en servir, devient assez tricky dès qu'on sort des alphabets français et anglais. Je suis même pas certain qu'il soit complètement défini.

    Citation Envoyé par aityahia Voir le message
    sinon je vois pas l’intérêt de la redéfinir
    Dans le même genre, il faudrait pouvoir détecter que "St Égrève" et "saint-egreve" sont la même chose. Et considérer que tous les types de tirets à mi-hauteur sont les mêmes. Pareil pour les apostrophes. Normalement les noms de ville avec espace sont censés être des espaces insécables, mais tout le monde n'y pense pas, alors il faut les considérer égaux.
    Sinon je ne vois pas l'intérêt de la redéfinir.

    La sémantique de equals(), est censée avoir une définition précise, donc limitée. Ce genre d'adaptations sont plutôt faites séparément, par un processus d'assainissement des input qui, lui, saura se satisfaire d'une définition complexe ou approximative. Voilà l'intérêt même si on s'occupe pas de l'insensibilité à la casse.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  9. #9
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Comme dit thelvin, si equals est redéfini, hashcode doit lui correspondre. Si tu fait des approximation dans equals, tu te retrouve coincé pour le hashcode.


    de plus, equals est censé indiquer qu'un objet peux être substitué à un autre. Dans un Set(), par exemple, cet objet ne sera donc présent qu'une fois. Si tu utiliser le ignore case, tu n'aura l'objet qu'un seule fois... Ca deviendra vite la galère au niveau de l'interface car, si la donnée est utilisé uen fois avec une fois sans majuscule, les gens verrons aléatoirement la version majuscule et la version sans, suivant l'instance qui aura eu la chance d'entre dans le set concerné...

    C'est la porte ouverte à des rendu instable, des bugs curieux, des comportements inexplicables.

    Sans compter que tu ne peux jamais garantir que celui qui utilisera equals pourra se contenter du ignore case.


    Quand à l'intérêt de redéfinir, ben à la base, c'est pour pouvoir comparer les contenu plutot que les instances, l'ignore case n'a rien à voir dans l'histoire

  10. #10
    Membre expert
    Avatar de aityahia
    Homme Profil pro
    CIEPTAL CARS SPA
    Inscrit en
    Mars 2006
    Messages
    1 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Algérie

    Informations professionnelles :
    Activité : CIEPTAL CARS SPA
    Secteur : Transports

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 938
    Points : 3 329
    Points
    3 329
    Par défaut
    Vous avez raison et c'est instructif, car il faut pas oublier que d'autres méthodes font appel a equal, d'ailleurs j'ai eu droit a mon lots d'exceptions (NullPointerException) en implémentant un DataBindig JFace. si la méthode doit être redéfinie, il faut prendre soin de gérer le cas des objets et des attributs null,

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

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