错误码:WMI_WRONG_MAP_ITERATOR
案例:
class="java">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();
?