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

时间:2012-01-22 16:11:16

标签: java collections hashmap linkedhashmap keyset

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

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()一起使用,那么迭代器没有几个键!

5 个答案:

答案 0 :(得分:48)

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

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

此外,在entrySet上循环更快,因为您不会为每个键查询两次映射。此外,Map.Entry实现通常会实现toString()方法,因此您无需手动打印键值对。

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

答案 1 :(得分:3)

每当你调用itr2.next()时,你都会获得一个独特的价值。价值不一样。你应该只在循环中调用一次。

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

答案 2 :(得分:2)

遍历大地图entrySet()要好于keySet()。检查this教程如何在entrySet(的帮助下优化对大对象的遍历以及它如何帮助进行性能调优。

答案 3 :(得分:1)

Iterator只向前移动,如果它只读了一次,就完成了。你的

m.get(itr2.next());

正在读取itr2.next();的下一个值,这就是为什么你缺少一些(实际上不是几个,每隔一个)键的原因。

答案 4 :(得分:0)

为了简单起见,请注意每次执行itr2.next()时指针移动到下一个元素,即如果您仔细注意,此处输出完全没有根据您编写的逻辑。
这可以帮助您更好地理解:

While循环的第一次迭代(指针在第一个元素之前):
键:if,value:2 {itr2.next()=if; m.get(itr2.next()=it)=>2}

While循环的第二次迭代(指针在第3个元素之前):
关键:是,价值:2 {itr2.next()=is; m.get(itr2.next()=to)=>2}

While循环的第3次迭代(指针在第5个元素之前):
关键:be,价值:1 {itr2.next()="be"; m.get(itr2.next()="up")=>"1"}

While循环的第四次迭代(指针在第7个元素之前):
关键:我,价值:1 {itr2.next()="me"; m.get(itr2.next()="delegate")=>"1"}

键:if,value:1
关键:它,价值:2
关键:是,价值:2
关键词:to,value:2
关键:be,值:1
关键:上,值:1
关键:我,价值:1
关键:代表,价值:1

打印:

Key:if,value:2
关键:是,价值:2
关键:be,值:1
关键:我,价值:1