像Python字典一样循环Java HashMap?

Posted

技术标签:

【中文标题】像Python字典一样循环Java HashMap?【英文标题】:Loop Java HashMap like Python Dictionary? 【发布时间】:2011-03-10 14:39:14 【问题描述】:

在 Python 中,您可以在字典中包含键、值对,您可以在其中循环访问它们,如下所示:

for k,v in d.iteritems():
    print k,v

有没有办法用 Java HashMaps 做到这一点?

【问题讨论】:

【参考方案1】:

是的 - 例如:

Map<String, String> map = new HashMap<String, String>();
// add entries to the map here

for (Map.Entry<String, String> entry : map.entrySet()) 
    String k = entry.getKey();
    String v = entry.getValue();
    System.out.printf("%s %s\n", k, v);

【讨论】:

对比一下 Python 版本让我想起了几年前我放弃 Java 的原因。【参考方案2】:

HashMap.entrySet() 将返回类似于dictionary.iteritems() 的键值对的bean。然后你可以循环它们。

我认为是最接近 Python 版本的东西。

【讨论】:

【参考方案3】:

如答案所示,基本上有两种方法可以迭代Map(在这些示例中假设Map&lt;String, String&gt;)。

    遍历Map#entrySet():

    for (Entry<String, String> entry : map.entrySet()) 
        System.out.println(entry.getKey() + "=" + entry.getValue());
    
    

    遍历Map#keySet(),然后使用Map#get()获取每个键的值:

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

第二个可能更具可读性,但它的性能成本是在每次迭代时都不必要地调用get()。有人可能会争辩说,创建键集迭代器的成本较低,因为它不需要考虑值。不管你信不信,keySet().iterator() 创建并使用了与entrySet().iterator() 相同的same 迭代器。唯一的区别是在keySet() 的情况下,迭代器的next() 调用返回it.next().getKey() 而不是it.next()

AbstractMap#keySet()'s javadoc 证明了这一点:

子类的迭代器方法在此映射的entrySet() 迭代器上返回一个“包装器对象”。

AbstractMap 源代码也证明了这一点。这是keySet() 方法的摘录(Java 1.6 中的第 300 行左右):

public Iterator<K> iterator() 
    return new Iterator<K>() 
        private Iterator<Entry<K,V>> i = entrySet().iterator(); // <-----

        public boolean hasNext() 
            return i.hasNext();
        

        public K next() 
            return i.next().getKey(); // <-----
        

        public void remove() 
            i.remove();
        
    ;


请注意,与过早优化相比,应优先考虑可读性,但记住这一点很重要。

【讨论】:

【参考方案4】:
Set<Map.Entry> set = d.entrySet();
for(Map.Entry i : set)
  System.out.println(i.getKey().toString() + i.getValue().toString);

类似的...

【讨论】:

【参考方案5】:

在 Java 中,您可以执行以下操作。

    HashMap<String, String> h = new HashMap<String, String>();
    h.put("1","one");
    h.put("2","two");
    h.put("3","three");

    for(String key:h.keySet())
        System.out.println("Key: "+ key + " Value: " + h.get(key));
    

【讨论】:

我没有投反对票,但这种方法比遍历 entryset 效率低。 get() 每次迭代都会产生额外费用。这至少不是循环遍历地图的“正确”方式。我可以想象有人因此而被否决,你的意图也有多好。 @BalusC - 是的,但是创建 MapEntrySet 迭代器(很可能)比创建集合迭代器更昂贵......我怀疑这是一个性能问题,即使这性能较差,我永远不会尝试通过优化这样的循环来解决性能问题。 (顺便说一句,我 +1)。 @Andreas_D:entryset 迭代器的创建并不昂贵。键集使用 same 迭代器作为入口集。另请参阅javadoc:子类的迭代器方法在此映射的 entrySet() 迭代器上返回一个“包装器对象”。 源代码确实证实了这一点:private Iterator&lt;Entry&lt;K,V&gt;&gt; i = entrySet().iterator(); public K next() return i.next().getKey();

以上是关于像Python字典一样循环Java HashMap?的主要内容,如果未能解决你的问题,请参考以下文章

提高 Python 中超大字典的性能

一日一技:在 Python 中像字典一样持久化数据

如何从 HashMap 中提取 ArrayList 并在 Java 中循环遍历它?

有没有办法在javascript中创建hashmap并像添加和删除值一样操作它

在循环Python中更新字典[重复]

Java中的Hashtable如何根据值获取键?