sonar掃描的嚴重問題對應。
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<String, Integer> params = new HashMap<String, Integer>(); params.put("resultID", 1); params.put("execID", 2); params.put("num", 3); Map<String, Object> mapOut = new HashMap<String, Object>(); // Map<String, Integer> 轉 HashMap<String, Object> Set<String> set = params.keySet(); for (String key : set) { Integer value = params.get(key); mapOut.put(key,value); }
意思是說要避免用.get(key),可能有點脫褲子放屁的感覺。
修改后
for (Map.Entry<String, Integer> entry : params.entrySet()) { mapOut.put(entry.getKey(),entry.getValue()); }
參考這篇
https://www.cnblogs.com/dreammyone/articles/9960400.html
還有這篇
https://blog.csdn.net/jdsjlzx/article/details/34487299
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方法的源代碼: 1. public V get(Object key) { 2. if (key == null) 3. return getForNullKey(); 4. int hash = hash(key.hashCode()); 5. for (Entry<K,V> e = table[indexFor(hash, table.length)]; 6. e != null; 7. e = e.next) { 8. Object k; 9. if (e.hash == hash && ((k = e.key) == key || key.equals(k))) 10. return e.value; 11. } 12. return null; 13. }
從這里可以看出查找value的原理,先計算出hashcode,然后散列表里取出entry,不管是計算hashcode,還是執行循環for以及執行equals方法,都是CPU密集運算,非常耗費CPU資源,如果對一個比較大的map進行遍歷,會出現CPU迅速飈高的現象,直接影響機器的響應速度,在並發的情況下,簡直就是一場災難。
解決方法: 1. for (Map.Entry<String, JMenu> entry : menuList.entrySet()) { 2. mb.add(entry.getValue());
}
for(Map.Entry<String, List<BlackListDO>> tempEntiy: companyBlackItemsMap.entrySet()) {
String key = tempEntiy.getKey();
List<BlackListDO> eachCompanyBlackItems = tempEntiy.getValue();