java 集合 - map 中的 keyset() vs entrySet()

我把一个字符串数组元素是一个映射,其中字符串数组的元素是键,单词的频率是值,例如:

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

然后地图将有这样的条目[ if:1, it:2 .... ]

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

打印所有键:"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());
}

打印所有键值对:

使用条目集打印所有值:

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

但是下面的代码块应该打印与上面完全相同的输出,但它不会:

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()));
}

它打印:

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

但是,如果我们在 while 循环中取消注释行 1,即

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

并注释该行

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

然后我们得到所有键:{"if","it","is","to","be","it","is","up","me","to","delegate"};

如果我们与 一起使用,那么迭代器就没有很少的键!m.get()itr2.next()


答案 1

对 的每次调用都会将迭代器移动到下一个元素。如果要在多个语句或表达式中使用当前元素,则必须将其存储在局部变量中。或者更好的是,你为什么不简单地使用一个 for-each 循环呢?Iterator.next()

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

此外,循环访问条目集的速度更快,因为您不必为每个键查询地图两次。此外,实现通常实现该方法,因此您不必手动打印键值对。Map.EntrytoString()

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

答案 2

每次调用 itr2.next() 时,你都会得到一个不同的值。不相同的值。您只应在循环中调用一次。

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