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

Collection et Stream Java Discussion :

Utilisation du HashMap


Sujet :

Collection et Stream Java

  1. #1
    Membre du Club
    Inscrit en
    Janvier 2009
    Messages
    139
    Détails du profil
    Informations forums :
    Inscription : Janvier 2009
    Messages : 139
    Points : 43
    Points
    43
    Par défaut Utilisation du HashMap
    Bonjour,

    je cherche à comprendre le principe utilisé par les HashMap(en quoi se basant pour déterminer l'unicité de la clé...) ainsi que leur utilisation de la methode equals() et hashcode(),

    merci d'avance,
    Cordialement

  2. #2
    Membre confirmé
    Inscrit en
    Juillet 2006
    Messages
    534
    Détails du profil
    Informations forums :
    Inscription : Juillet 2006
    Messages : 534
    Points : 562
    Points
    562
    Par défaut
    Bonjour,

    Tu peux lire ceci http://java.developpez.com/faq/java/

  3. #3
    Membre du Club
    Inscrit en
    Janvier 2009
    Messages
    139
    Détails du profil
    Informations forums :
    Inscription : Janvier 2009
    Messages : 139
    Points : 43
    Points
    43
    Par défaut
    Voici le problème que j'ai rencontré et qui pourra interesser les prochains java certifié:
    import java.util.*;
    class MapEQ {
    public static void main(String[] args) {
    Map<ToDos, String> m = new HashMap<ToDos, String>();
    ToDos t1 = new ToDos("Monday");
    ToDos t2 = new ToDos("Monday");
    ToDos t3 = new ToDos("Tuesday");
    m.put(t1, "doLaundry");
    m.put(t2, "payBills");
    m.put(t3, "cleanAttic");
    System.out.println(m.size());
    } }
    class ToDos{
    String day;
    ToDos(String d) { day = d; }
    public boolean equals(Object o) {
    return ((ToDos)o).day == this.day;
    }
    // public int hashCode() { return 9; }
    }
    Which is correct? (Choose all that apply.)
    A. As the code stands it will not compile.
    B. As the code stands the output will be 2.
    C. As the code stands the output will be 3.
    D. If the hashCode() method is uncommented the output will be 2.
    E. If the hashCode() method is uncommented the output will be 3.
    F. If the hashCode() method is uncommented the code will not compile.
    moi j'au choisi la reponse B puisque les hashmap ne permet pas la duplication des clés alors que la réponse correcte est C et D!!!

  4. #4
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    Citation Envoyé par khaigo Voir le message
    moi j'au choisi la reponse B puisque les hashmap ne permet pas la duplication des clés
    Rappelons-nous que c'est une classe *Hash*Map. Le fait qu'il ne permette pas la duplication des clés dépend du hashCode() de ces clés. La méthode equals() pour différencier deux clés n'est appelée que si leurs hashCode() sont identiques.

    Or, dans le programme donné, hashCode() est commenté, ce qui veut dire que leur méthode hashCode() est héritée de la classe Object, où chaque objet distinct a un hashCode distinct.
    Il s'agit d'une violation de contrainte sur la redéfinition de equals() et hashCode(), qui dit que si on redéfinit equals() ou hashCode(), on doit faire en sorte que a.equals(b) == true implique que a.hashCode() == b.hashCode().

    Bref, ce programme utilise 3 clés avec chacune son hashCode différent, donc le HashMap n'appelle pas equals() et il accepte les 3 entrées distinctes.

    Si on décommente hashCode(), là les 3 clés ont un hashCode identique, elles sont donc différenciées en appelant equals() et deux d'entre elles sont déterminées égales par cette méthode. Donc le HashMap n'accepte que 2 entrées distinctes.

    Ce n'est pas évident évident, je trouve.

    Surtout qu'au fond, tout le monde ne sait pas que "Monday" == "Monday".
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  5. #5
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2009
    Messages
    156
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2009
    Messages : 156
    Points : 190
    Points
    190
    Par défaut
    Par contre un piège traitre à propos des Maps, c'est que les TreeMap et HashMap utilisent d'autres critères d'égalités !!!

  6. #6
    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
    Salut,

    Citation Envoyé par khaigo Voir le message
    moi j'au choisi la reponse B puisque les hashmap ne permet pas la duplication des clés alors que la réponse correcte est C et D!!!
    Les réponses C & D sont normales.

    Les Map utilisent des index basé sur le hashCode pour rechercher rapidement les clefs. Cela permet d'éviter de comparer un à un toutes les clefs de la Map.

    C'est tout l'intérêt des Map sur de grosse quantité de données


    Pour rechercher une clef, elle suit donc ces étapes :
    • Elle récupère le hashCode de la clef, ce qui permet de récupérer un nombre limité de clef contenu dans la Map. En fait il faut considérer que les clef avec le même hashCode sont "rangé" ensemble...
    • Elle utilise ensuite equals() pour vérifier réellement l'égalité des clefs, mais seulement sur les clefs ayant le même hashCode.

    Cela permet une recherche rapide des clef même sur de grand ensemble !


    Que se passe-il ici ?
    La méthode hashCode() est commenté, et donc on hérite de l'implémentation de base qui tente au maximum de renvoyer un nombre différent pour chaque instance. Il y a de très forte chance que tes 3 instance ait donc un hashCode différent.

    Du coup les différentes clefs sont "rangées" à des emplacements différents, et on ne passe pas par la comparaison.

    En fait le problème vient du fait que la méthode hashCode() est incorrect. Lorsque tu redéfini equals() tu dois redéfinir hashCode() de manière cohérente (voir FAQ : equals() et hashCode()).



    Ici la Map considère que les objets ne peuvent pas être égaux étant-donné qu'ils ont tous un hashCode différent, et du coup elle n'utilise pas equals().


    En fait ce "problème" vient du fait que la classe ToDos ne respecte pas la règle de base entre equals() et hashCode() :
    • Si A.equals(B) alors A.hashCode() == B.hashCode()
    • Si A.hashCode()!=B.hashCode() alors A.equals(B)==false

    (attention les réciproques ne sont pas vrai)



    Que se passe-t-il lorsqu'on décommente la méthode hashCode() qui se contente de retourner 9 ?
    On respecte désormais ces règles, et la Map va donc comparer les clefs entre elle afin de réellement vérifier l'identité des clefs, et donc éviter le doublons.


    Toutefois cette implémentation de hashCode() n'est pas du tout optimisé car cela va placer toutes les clefs ensemble, ce qui fait perdre tout l'intérêt des Map...




    Dans le même genre, il faut éviter d'utiliser des objets muables comme clef, car on risque alors de ne plus pouvoir y accéder...


    a++

  7. #7
    Membre du Club
    Inscrit en
    Janvier 2009
    Messages
    139
    Détails du profil
    Informations forums :
    Inscription : Janvier 2009
    Messages : 139
    Points : 43
    Points
    43
    Par défaut
    merci les amis,
    c'est très riche comme réponses,
    bonne journée

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

Discussions similaires

  1. JNI: comment utiliser une hashmap
    Par loicounet dans le forum Entrée/Sortie
    Réponses: 0
    Dernier message: 29/06/2010, 16h41
  2. Probleme d'utilisation avec Hashmap
    Par zouboumafou dans le forum Collection et Stream
    Réponses: 2
    Dernier message: 14/05/2010, 02h32
  3. [Pratiques] Utilisation de HashMap dans une application
    Par Jimalexp dans le forum Collection et Stream
    Réponses: 10
    Dernier message: 17/02/2009, 13h01
  4. Utiliser une HashMap dans un tableModel
    Par Jefeh dans le forum Composants
    Réponses: 3
    Dernier message: 10/12/2008, 15h13
  5. Utilisation de HashMap
    Par jean3xw dans le forum Collection et Stream
    Réponses: 4
    Dernier message: 29/10/2008, 22h46

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