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 :

Méthode equals() et les hashSet


Sujet :

avec Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2010
    Messages
    20
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Décembre 2010
    Messages : 20
    Par défaut Méthode equals() et les hashSet
    Bonjour,

    Je suis autodidacte en Java et bien que j'ai résolu mon problème à l'aide de la rubrique suivante : http://java.developpez.com/faq/java/...#DIVERS_equals, je n'ai toujours pas compris pourquoi mon ancien code ne fonctionnait pas.

    Je dispose d'une classe Tag possédant entre autre un champ String Name (c'est le seul important ici). Je souhaite pouvoir utiliser les ensembles hashSet<Tag> pour la rapidité des méthodes add, remove, et contains, et surtout pour l'élimination automatique des doublons.
    J'ai donc redéfinit les méthodes hashCode et equals comme celà :

    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
     
    public class Tag
    {
    	private String name;
            private SomeType lotsOfOtherStuff;
     
           public Tag(String name) //constructeur
           {
                 this.name = name;
                 this.lotsOfOtherStuff = WhatItNeedToBe;
           }
     
           public getName()
           {return this.name;}
     
          public hashCode()
          {return this.name.hashCode();}
     
          public equals(Tag t)
          {
               return this.name.equals(t.getName());
          }
    }
    Et voici mon main dans lequelle je réalise mes tests :

    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
     
    public class TestProto
    {
    	public static void main(String[] args)
    	{
    		// test des hashSet<Tag> :
    		System.out.println("Etape de test n°0 : teste des HashSet de Tags :");
    		HashSet<Tag> listeTag = new HashSet<Tag>();
    		Tag T1 = new Tag("test");
    		Tag T2 = new Tag("test");
    		System.out.println("T1.equals(T2) ? : " + T1.equals(T2) + " =?= VRAI");
     
    		System.out.println("T1.hashCode() == T2.hashCode() ? :" + (T1.hashCode() == T2.hashCode()) + " =?= VRAI");
     
    		listeTag.add(T1);
    		System.out.println("listeTag.add(T2) ? : " + listeTag.add(T2) + " =?= FAUX");

    Voici ce que j'obtiens lors de l'éxécution :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Etape de test n°0 : teste des HashSet de Tags :
    T1 == T2 ? : true =?= VRAI                                         <-- la méthode equals renvoie le bon résultat
    T1.hashCode() == T2.hashCode() ? :true =?= VRAI     <-- la méthode hashCode fonctionne comme prévu
    listeTag.add(T2) ? : true =?= FAUX                             <-- pourtant T2 est quand même rajouter à mon hashSet...

    La correction de la méthode equals à l'aide du lien plus haut résoud mon problème, mais çà ne me dit pas pourquoi avant çà ne marchait pas. Auriez-vous des explications svp ?

    Voici à titre indicatif ma nouvelle méthode equals :

    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
     
    	public boolean equals(Object T)
    	{	// Vérificationde la référence
    		if (T==this)
    			return true;
     
    		//Vérification du type du paramètre puis de ses attributs.
    		if (T instanceof Tag)
    		{
    			Tag Tbis = (Tag) T;
    			return this.name.equals(Tbis.getName());
     
    		} else
    			return false;
    	}

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

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    parce que, en utilisant le premier cas, ton objet à deux méthodes equals, avec des signature différente.

    equals(Tag) (que tu as créé)
    et
    equals(Object) (dont tu hérite).


    Et c'est toujoursl a deuxième qu'il faut redéfinir, la première n'étant qu'une méthode à toi que seul Tag utilise.

    Pour t'en convaincre, rajoute dans ton test le code suivant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    		System.out.println("T1.equals((Object)T2) ? : " + T1.equals((Object)T2) + " =?= VRAI");

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2010
    Messages
    20
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Décembre 2010
    Messages : 20
    Par défaut
    C'est justement ce que je ne comprends pas :

    equals(Tag) est plus spécifique que equals(Object) puisqu'en Java tous les objets dérive de la classe Object.

    Comme T1 et T2 sont tous deux de type Tag, la méthode plus spécifique equals(Tag) convient et devrait être appelé avant la méthode equals(Object), non ?

  4. #4
    Membre Expert
    Inscrit en
    Août 2009
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Août 2009
    Messages : 1 073
    Par défaut
    La méthode est appelée dans une autre classe générique. Celle ci n'a aucune raison de connaitre le type de l'objet (le type générique est effacé à la compilation) ; en conséquence elle ne peut pas savoir qu'il faut appeler equals(Tag) ; pour elle, tout se passe avec equals(Object).

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2010
    Messages
    20
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Décembre 2010
    Messages : 20
    Par défaut
    Citation Envoyé par Rei Ichido Voir le message
    (le type générique est effacé à la compilation) ; en conséquence elle ne peut pas savoir qu'il faut appeler equals(Tag) ; pour elle, tout se passe avec equals(Object).
    Super merci ! J'ai appris quelque chose.
    Peut-on espérer un changement de ce comportement lors d'une futur mise à jour de Java ?

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

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    non, le typage des méthode (pour rechercher la méthode la plus spécifique) se fait par le compilateur, pas par la jvm (java n'est pas interprété). la méthode equals(Objet) n'est pas la méthode equals(Tag), aucune ne cache l'autre, ce sont des méthodes séparées! D'ailleurs si vous mettez @override sur votre méthode, vous contaterez que le compilateur vous dit qu'elle ne surcharge aucune méthode existante.

    Vouloir un changement là dessus, c'est vouloir qu'on change toutes les règles du java! Et ca n'a de toutes façons aucun sens.

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

Discussions similaires

  1. Générer (en code JAVA) la méthode equals dans les classes bindées par JAXB2
    Par greatmaster1971 dans le forum Format d'échange (XML, JSON...)
    Réponses: 0
    Dernier message: 11/12/2013, 16h55
  2. fonctionnent de la méthode run dans les threads
    Par L4BiN dans le forum Concurrence et multi-thread
    Réponses: 8
    Dernier message: 25/07/2006, 11h06
  3. Réponses: 3
    Dernier message: 13/06/2006, 14h52
  4. BINARY, NOT IN, NOT EQUAL... et les Index !
    Par Acti dans le forum Requêtes
    Réponses: 2
    Dernier message: 23/03/2006, 17h22
  5. Les méthodes abstraites et les interfaces
    Par ETI-trian dans le forum Langage
    Réponses: 3
    Dernier message: 17/01/2006, 12h14

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