这段时间项目正在使用findbugs来进行静态代码检测:
其中有一个WMI_WRONG_MAP_ITERATOR警告,提示说需要用更高效的迭代方式来进行Map迭代。
例如,有一个HashMap需要进行遍历并使用里面的所有键值对,写法是这样的:
private void getMapValues(HashMap<String,String> map){ <span style="white-space:pre"> </span>HashMap<String,String> newMap =new HashMap<>(); <span style="white-space:pre"> </span>Set<String> keySet =map.keySet(); for(String key:keySet){ newMap.put(key,map.get(key)); } }这样的迭代将影响性能,因为Map的get方法里也在做遍历,以下是HashMap中get方法的源码:
/** * Returns the value of the mapping with the specified key. * * @param key * the key. * @return the value of the mapping with the specified key, or {@code null} * if no mapping for the specified key is found. */ public V get(Object key) { if (key == null) { HashMapEntry<K, V> e = entryForNullKey; return e == null ? null : e.value; } int hash = Collections.secondaryHash(key); HashMapEntry<K, V>[] tab = table; for (HashMapEntry<K, V> e = tab[hash & (tab.length - 1)]; e != null; e = e.next) { K eKey = e.key; if (eKey == key || (e.hash == hash && key.equals(eKey))) { return e.value; } } return null; }
我们将其改成更高效的entrySet迭代方法:
private void getMapValues(HashMap<String,String> map){ HashMap<String,String> newMap =new HashMap<>(); Set<Map.Entry<String,String>> keySet =map.entrySet(); for (Map.Entry<String,String> entry:keySet){ newMap.put(entry.getKey(),entry.getValue()); } }