Java:通过HashMap迭代,哪个更有效?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (10)

给定以下代码,用两种替代方法遍历它, 这两种方法之间是否存在性能差异?

        Map<String, Integer> map = new HashMap<String, Integer>();
        //populate map

        //alt. #1
        for (String key : map.keySet())
        {
            Integer value = map.get(key);
            //use key and value
        }

        //alt. #2
        for (Map.Entry<String, Integer> entry : map.entrySet())
        {
            String key = entry.getKey();
            Integer value = entry.getValue();
            //use key and value
        }

我倾向于认为这alt. #2是更有效的遍历整个map的方法

提问于
用户回答回答于

你的第二个选项肯定更有效率,因为你只进行一次查找,而第一个选项的次数是n次。

但是,没有什么比在可能的情况下试用更好。所以在这里 -

public static void main(String args[]) {

    Map<String, Integer> map = new HashMap<String, Integer>();
    // populate map

    int mapSize = 500000;
    int strLength = 5;
    for(int i=0;i<mapSize;i++)
        map.put(RandomStringUtils.random(strLength), RandomUtils.nextInt());

    long start = System.currentTimeMillis();
    // alt. #1
    for (String key : map.keySet()) {
        Integer value = map.get(key);
        // use key and value
    }
    System.out.println("Alt #1 took "+(System.currentTimeMillis()-start)+" ms");

    start = System.currentTimeMillis();
    // alt. #2
    for (Map.Entry<String, Integer> entry : map.entrySet()) {
        String key = entry.getKey();
        Integer value = entry.getValue();
        // use key and value
    }
    System.out.println("Alt #2 took "+(System.currentTimeMillis()-start)+" ms");
}

结果

使用int mapSize = 5000; int strLength = 5; Alt#1花了26 ms, Alt#2花了20 ms

使用int mapSize = 50000; int strLength = 5; Alt#1花费32毫秒 替代花费了20毫秒

int mapSize = 50000; int strLength = 50; Alt#1花了22 ms, Alt#2花了21 ms

使用int mapSize = 50000; int strLength = 500; Alt#1花费了28毫秒 Alt#2花费了23毫秒

int mapSize = 500000; int strLength = 5; Alt#1花了92毫秒 Alt#2花了57毫秒

用户回答回答于

第二个片段会稍微快一点,因为它不需要重新查找密钥。

所有HashMap迭代器都调用该nextEntry方法,该方法返回一个Entry<K,V>

你的第一个片段放弃条目(in KeyIterator)中的值,然后再次在库中查找它。

你的第二个片段直接使用键和值(来自EntryIterator

扫码关注云+社区