web-dev-qa-db-fra.com

java collections - keyset () vs entrySet () dans la carte

Je mets un élément de tableau de chaînes est une carte où les éléments du tableau de chaînes sont la clé et la fréquence de Word est la valeur, par exemple:

String[] args = {"if","it","is","to","be","it","is","up","me","to","delegate"};

alors la carte aura des entrées comme [ if:1, it:2 .... ]

Set<String> keys = m.keySet();
System.out.println("keyset of the map : "+keys);

imprime toutes les clés: "if","it","is","to","be","it","is","up","me","to","delegate"

Set<Map.Entry<String, Integer>> entrySet = m.entrySet();
Iterator<Map.Entry<String, Integer>> i = entrySet.iterator();
while(i.hasNext()){
    Map.Entry<String, Integer> element = i.next();
    System.out.println("Key: "+element.getKey()+" ,value: "+element.getValue());
}

imprime toutes les paires de valeurs clés:

L'utilisation du jeu d'entrées imprime toutes les valeurs:

Key: if ,value: 1
Key: it ,value: 2
Key: is ,value: 2
Key: to ,value: 2
Key: be ,value: 1
Key: up ,value: 1
Key: me ,value: 1
Key: delegate ,value: 1

Mais le bloc de code ci-dessous devrait imprimer exactement la même sortie que ci-dessus, mais il ne le fait pas:

Iterator<String> itr2 = keys.iterator();
while(itr2.hasNext()){
    //System.out.println(itr1.next()+" ");
    //System.out.println(m.get(itr1.next())+" ");
    System.out.println("Key: "+itr2.next()+" ,value: "+m.get(itr2.next()));
}

Il imprime:

Key: if ,value: 2
Key: is ,value: 2
Key: be ,value: 1
Key: me ,value: 1

Mais si nous décommentons la ligne 1 dans la boucle while c'est-à-dire

System.out.println(itr1.next()+" ");

et commenter la ligne

System.out.println("Key: "+itr2.next()+" ,value: "+m.get(itr2.next()));

Ensuite, nous obtenons toutes les clés: {"if","it","is","to","be","it","is","up","me","to","delegate"};

Si nous utilisons m.get() avec itr2.next(), alors l'itérateur n'a pas quelques touches!

32
NINCOMPOOP

Chaque appel à la Iterator.next() déplace l'itérateur vers l'élément suivant. Si vous souhaitez utiliser l'élément actuel dans plusieurs instructions ou expressions, vous devez le stocker dans une variable locale. Ou encore mieux, pourquoi n'utilisez-vous pas simplement une boucle pour chaque?

for (String key : map.keySet()) {
    System.out.println(key + ":" + map.get(key));
}

De plus, la boucle sur le entrySet est plus rapide, car vous n'interrogez pas la carte deux fois pour chaque clé. De plus, les implémentations Map.Entry Implémentent généralement la méthode toString(), vous n'avez donc pas besoin d'imprimer la paire clé-valeur manuellement.

for (Entry<String, Integer> entry : map.entrySet()) {
    System.out.println(entry);
}
48
Natix

Chaque fois que vous appelez itr2.next (), vous obtenez une valeur distincte. Pas la même valeur. Vous ne devez l'appeler qu'une seule fois dans la boucle.

Iterator<String> itr2 = keys.iterator();
    while(itr2.hasNext()){
        String v = itr2.next();
        System.out.println("Key: "+v+" ,value: "+m.get(v));
    }
3
Vincent Ramdhanie

La traversée sur la grande carte entrySet() est bien meilleure que la keySet(). Vérifiez ce tutoriel comment ils optimisent la traversée sur le grand objet à l'aide de entrySet() et comment cela aide à l'optimisation des performances.

2
RED.Skull

Un Iterator avance uniquement, s'il l'a lu une fois, c'est fait. Votre

m.get(itr2.next());

lit la valeur suivante de itr2.next();, c'est pourquoi il vous manque quelques touches (en fait pas quelques-unes, toutes les autres).

1
kosa

Pour simplifier les choses, veuillez noter que chaque fois que vous faites itr2.next() le pointeur se déplace vers l'élément suivant, c'est-à-dire ici si vous le remarquez attentivement, la sortie est parfaitement correcte selon la logique que vous avez écrite.
Cela peut vous aider à mieux comprendre:

1ère itération de la boucle While (le pointeur est avant le 1er élément):
Touche: si, valeur: 2 {itr2.next()=if; m.get(itr2.next()=it)=>2}

2e itération de la boucle While (le pointeur est avant le 3e élément):
Touche: est, valeur: 2 {itr2.next()=is; m.get(itr2.next()=to)=>2}

3e itération de la boucle While (le pointeur est avant le 5e élément):
Touche: be, valeur: 1 {itr2.next()="be"; m.get(itr2.next()="up")=>"1"}

4ème itération de la boucle While (le pointeur est avant le 7ème élément):
Touche: moi, valeur: 1 {itr2.next()="me"; m.get(itr2.next()="delegate")=>"1"}

Clé: si, valeur: 1
Clé: it, valeur: 2
Clé: est, valeur: 2
Clé: à, valeur: 2
Clé: be, valeur: 1
Touche: haut, valeur: 1
Clé: moi, valeur: 1
Clé: délégué, valeur: 1

Il imprime:

Clé: si, valeur: 2
Clé: est, valeur: 2
Clé: be, valeur: 1
Clé: moi, valeur: 1

0
curiousManish