entrySet和keySet之比较

错误码:WMI_WRONG_MAP_ITERATOR
案例:

StringBuffer resultDetail = new StringBuffer();
Iterator<String> it = resultDetailMap.keySet().iterator();
while (it.hasNext()) {
        String key = it.next().toString();
        resultDetail.append("标的号:" + entry.getKey() + ",原因:" + entry.getValue());
}
return resultDetail.toString();

Bug: Method JTAMainFrame.initView(JFrame) makes inefficient use of keySet iterator instead of entrySet iterator
Pattern id: WMI_WRONG_MAP_ITERATOR, type: WMI, category: PERFORMANCE

This method accesses the value of a Map entry, using a key that was retrieved from a keySet iterator. It is more efficient to use an iterator on the entrySet of the map, to avoid the Map.get(key) lookup.

 

解释:
很多人都这样遍历Map,没错,但是效率很低,先一个一个的把key遍历,然后在根据key去查找value,这不是多此一举么,为什么不遍历entry(桶)然后直接从entry得到value呢?它们的执行效率大概为1.5:1。
我们看看HashMap.get方法的源代码:

public V get(Object key) {    
    if (key == null)    
        return getForNullKey();    
    int hash = hash(key.hashCode());    
    for (Entry<K,V> e = table[indexFor(hash, table.length)];    
         e != null;    
         e = e.next) {    
        Object k;    
        if (e.hash == hash && ((k = e.key) == key || key.equals(k)))    
            return e.value;    
    }    
    return null;    
}

从这里可以看出查找value的原理,先计算出hashcode,然后散列表里取出entry,不管是计算hashcode,还是执行循环for以及执行 equals方法,都是CPU密集运算,非常耗费CPU资源,如果对一个比较大的map进行遍历,会出现CPU迅速飚高的现象,直接影响机器的响应速度,在并发的情况下,简直就是一场灾难。

解决方法:

StringBuffer resultDetail = new StringBuffer();
for (Entry<String, String> entry : resultDetailMap.entrySet()) {
        resultDetail.append("标的号:" + entry.getKey() + ",原因:" + entry.getValue());
}
return resultDetail.toString();

 

你可能感兴趣的:(java,HashMap,keyset,entrySet)