Java HashMap 遍历方式性能探讨

  • 2017-08-28
  • 浏览 (915)

JDK8之前,可以使用keySet或者entrySet来遍历HashMap,JDK8中引入了map.foreach来进行遍历。

原因:

    keySet其实是遍历了2次,一次是转为Iterator对象,另一次是从hashMap中取出key所对应的value。而entrySet只是遍历了一次就把key和value都放到了entry中,效率更高。如果是JDK8,使用Map.foreach方法。

1. keySet和entrySet

1.1 基本用法
keySet:
Map map=new HashMap();
Iterator it=map.keySet().iterator();
Object key;
Object value;
while(it.hasNext()){
    key=it.next();
    value=map.get(key);
    System.out.println(key+":"+value);
}
entrySet:
Map map=new HashMap();
Iterator it=map.entrySet().iterator();
Object key;
Object value;
while(it.hasNext()){
    Map.Entry entry = (Map.Entry)it.next();
    key=entry.getKey();
    value=entry.getValue();
    System.out.println(key+"="+value);
}

源码上看:
keySet:
final class KeyIterator extends HashIterator
    implements Iterator<K> {
    public final K next() { return nextNode().key; }
}
entrySet:
final class EntryIterator extends HashIterator
    implements Iterator<Map.Entry<K,V>> {
    public final Map.Entry<K,V> next() { return nextNode(); }
}
其实这里已经很明显了,当要得到某个value时,keySet还需要从HashMap中get,entrySet相比keySet少了遍历table的过程,这也是两者性能上的主要差别。

2. Map.foreach

在JDK8以后,引入了Map.foreach。

Map.foreach本质仍然是entrySet
default void forEach(BiConsumer<? super K, ? super V> action) {
    Objects.requireNonNull(action);
    for (Map.Entry<K, V> entry : entrySet()) {
        K k;
        V v;
        try {
            k = entry.getKey();
            v = entry.getValue();
        } catch(IllegalStateException ise) {
            // this usually means the entry is no longer in the map.
            throw new ConcurrentModificationException(ise);
        }
        action.accept(k, v);
    }
}
配合lambda表达式一起使用,操作起来更加方便。

2.1 使用Java8的foreach+lambda表达式遍历Map
Map<String, Integer> items = new HashMap<>();
items.put("A", 10);
items.put("B", 20);
items.put("C", 30);
items.put("D", 40);
items.put("E", 50);
items.put("F", 60);

items.forEach((k,v)->System.out.println("Item : " + k + " Count : " + v));

items.forEach((k,v)->{
    System.out.println("Item : " + k + " Count : " + v);
    if("E".equals(k)){
        System.out.println("Hello E");
    }
});
 
Reference:

1. http://lizhuang.iteye.com/blog/2356044

2. http://blog.163.com/fw_long/blog/static/51771186201392982041337/

3. https://yq.aliyun.com/articles/44712


原文出处:https://my.oschina.net/hosee/blog/1488876
0  赞