Afficher un hashmap [Résolu]

Signaler
Messages postés
130
Date d'inscription
lundi 14 août 2017
Statut
Membre
Dernière intervention
25 février 2021
-
Messages postés
16254
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
25 février 2021
-
Bonjour, je rencontre des difficultés actuellement en voulait afficher un hashmap, avec le code suivant:

Mot bonjour = new Mot("bonjour");
        Key clef = new Key(bonjour);

        HashMap<Key, Mot> hashmap = new HashMap<>();
        hashmap.put(clef,bonjour);
        System.out.println(hashmap.size());

        for (Map.Entry m: hashmap.entrySet()) {
            System.out.println(m.getKey() + " " + m.getValue());
        }


le résultat est le suivant:

1
com.company.Key@3feba861 bonjour


(l'objet Key se résume à un attribut de type int)

Comment puis-je arranger ça ?

3 réponses

Messages postés
16254
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
25 février 2021
2 798
Bonjour,

Il faut surcharger la méthode toString() dans la classe Key, comme c'est fait dans la classe Mot.
Messages postés
130
Date d'inscription
lundi 14 août 2017
Statut
Membre
Dernière intervention
25 février 2021
1
effectivement, ça marche, merci !
Messages postés
130
Date d'inscription
lundi 14 août 2017
Statut
Membre
Dernière intervention
25 février 2021
1
Par contre, j'aimerais bien afficher également la clef à partir d'une valeur, avec
hm.hashmap.get(mot)

mais j'ai un
null
en guise de résultat (sachant que hm est un objet qui n'a pour attribut qu'un HashMap).

j'ai essayé avec
hm.hashmap.get(bonjour).toString()
mais ça ne marche pas.


qu'est-ce que je pourrais essayer de plus?
Messages postés
16254
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
25 février 2021
2 798
"afficher également la clef à partir d'une valeur"
Une Map garantie que la clé est unique, mais on peut avoir plusieurs fois la même valeur. Donc une recherche par valeur peut renvoyer plusieurs résultats.

Par exemple tu peux faire map.put(k1, v) et map.put(k2, v). Dans ce cas une recherche de la valeur v devrait te renvoyer k1 et k2.

Une telle recherche n'est pas prévue pour les Map, tu peux considérer l'EntrySet comme une liste et faire la recherche à la main, mais les performances ne seront pas bonnes.
Éventuellement, si dans ton cas tu es sûr que chaque valeur sera associée à une seule clé, tu peux maintenir une deuxième Map inversée.

C'est à dire avoir une Map<K,V> valueByKey, et une Map<V,K> keyByValue, et à chaque ajout faire valueByKey.put(k,v) et keyByValue.put(v,k), afin de pouvoir faire la recherche dans un sens ou dans un autre.

Remarque : de même que tu avais oublié la méthode toString, assures toi de ne pas oublier de surcharger les méthodes hashCode et equals, sinon les Map ne feront pas ce que tu penses.
Messages postés
130
Date d'inscription
lundi 14 août 2017
Statut
Membre
Dernière intervention
25 février 2021
1
je sais d'avance qu'il y aura plusieurs clefs pour une même valeur, donc je pense que je vais laisser tomber l'idée du coup. Je pensais que c'était utile d'implémenter la méthode, au cas où... mais apparemment pas en fin de compte. Merci encore pour ton aide.

Par contre, il y a un truc que je ne comprends pas, c'est ceci:
System.out.println("hm constains value \"bonjour\"? " + hm.containsValue(bonjour));
System.out.println("hm constains value \"bonjour\"? " + hm.hashmap.containsValue(bonjour));


j'ai deux résultats différents, alors que ça devrait me retourner true dans les 2 cas:
hm constains value "bonjour"? false
hm constains value "bonjour"? true


voici la méthode utilisée en question:
public boolean containsValue(Mot mot){
        return this.hashmap.containsValue(mot.getMot().toString());
    }

sachant que ma classe ne contient qu'un seul attribut:
public HashMap<Key, Mot> hashmap;
Messages postés
16254
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
25 février 2021
2 798
hm.containsValue(bonjour)
est équivalent à
hm.hashmap.containsValue(mot.getMot().toString())
, c'est à dire que tu fais une recherche d'un String dans une map dont les valeurs sont des Mot.
Comme les deux objets sont de types différents ils ne peuvent pas être égaux.

Ceci aurait été plus juste :
public boolean containsValue(Mot mot) {
    return hashmap.containsValue(mot);
}
Messages postés
130
Date d'inscription
lundi 14 août 2017
Statut
Membre
Dernière intervention
25 février 2021
1 >
Messages postés
16254
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
25 février 2021

effectivement, ça marche, merci
Par contre, pourquoi supprimer le this ? Je pensais que c'était absolument nécessaire de le mettre pour faire allusion à l'objet sur lequel on appelle la fonction.
Messages postés
16254
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
25 février 2021
2 798 >
Messages postés
130
Date d'inscription
lundi 14 août 2017
Statut
Membre
Dernière intervention
25 février 2021

this est implicite, si tu ne le mets pas il y sera par défaut.
Il n'y a que dans trois cas où this est vraiment utile :
  • lorsque tu as une variable de même nom que l'attribut de classe, typiquement dans les constructeurs : this.toto = toto;
  • lorsque l'objet courant doit être manipulé, que ce soit directement (this == toto) ou en paramètre d'une méthode : toto(this);
  • lorsqu'un constructeur appelle un autre constructeur de la même classe : this(toto)
Messages postés
130
Date d'inscription
lundi 14 août 2017
Statut
Membre
Dernière intervention
25 février 2021
1 >
Messages postés
16254
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
25 février 2021

d'accord, merci pour ta réponse.

Au passage, j'essaie d'afficher les éléments d'une arraylist contenue dans
HashMap<Key, ArrayList<Mot>>
avec ces méthodes.

// ajout d'un mot via ArrayList et sa clef correspondante
    public void put(Key key, Mot mot){
        ArrayList<Mot> anagramme = new ArrayList();
        anagramme.add(mot);

        this.hashmap.put(key,anagramme);
    }

// retourne le ou les élément(s) à partir d'une clef
    public String get(Key key){
        return this.hashmap.get(key).toString();
    }


résultat: quand je fais un
hashmap.get(key)
, je n'ai que le premier élément de l'arrayList.
Est-ce que j'ai fait une erreur avec mes méthodes ?
Messages postés
16254
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
25 février 2021
2 798 >
Messages postés
130
Date d'inscription
lundi 14 août 2017
Statut
Membre
Dernière intervention
25 février 2021

Le problème c'est que à chaque fois que tu fais un put tu crées une nouvelle liste, alors qu'il faudrait faire des add sur la liste qui existe déjà (quand elle existe).

public void put(Key key, Mot mot) {
    ArrayList<Mot> anagramme = hashmap.get(Key);
    if (anagramme == null) {
        anagramme = new ArrayList<>();
        hashmap.put(key, anagramme);
    }
    anagramme.add(mot);
}

public ArrayList<Mot> get(Key key) {
    return hashmap.get(key);
}