Map遍歷KeySet()和EntrySet的效能差異與原始碼解析
Set<Entry<String, String>>entrySet =map.entrySet();
Set<String>set=map.keySet();`
上面就是我們經常用Map進行遍歷的兩種方式,在此對比一下兩者的區別
在此我們看一下原始碼解析:
keySet:get方式和getEntry方式的比較
public V get(Object key) {
if (key == null)
return getForNullKey();
Entry<K,V> entry = getEntry(key);
return null == entry ? null : entry.getValue();
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
final Entry<K,V> getEntry(Object key) {
if (size == 0) {
return null;
}
int hash = (key == null) ? 0 : hash(key);
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 != null && key.equals(k))))
return e;
}
return null;
}
從上面兩個方式的可以看出
使用entrySet遍歷Map類集合KV,而不是keySet方式進行遍歷。
說明:keySet其實是遍歷了2次,一次是轉為Iterator物件,另一次是從hashMap中取出 key所對應的value。而entrySet只是遍歷了一次就把key和value都放到了entry中,效率更高。如果是JDK8,使用Map.foreach方法。
正例:values()返回的是V值集合,是一個list集合物件;keySet()返回的是K值集合,是一個Set集合物件;entrySet()返回的是K-V值組合集合。
例子:第一種
Set<Entry<String,
String>>entrySet
=map.entrySet();Set<String>set=map.keySet();`
Map map = new HashMap();
Iterator iter = map.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry entry = (Map.Entry) iter.next();
Object key = entry.getKey();
Object val = entry.getValue();
}
效率高,以後一定要使用此種方式!
例子:第二種
Map map = new HashMap();
Iterator iter = map.keySet().iterator();
while (iter.hasNext()) {
Object key = iter.next();
Object val = map.get(key);
}
效率低,以後儘量少使用!
Tips:對於兩種遍歷方式我們構造程式碼的時候一定要注意,一定要寫出高質量的程式碼是我們畢生追求,寫出藝術感,使命感,下面想說一下阿里Java開發手冊的注意Map類集合K/V能不能儲存null值的情況,如下表格:
集合類 |
Key |
Value |
Super |
說明 |
Hashtable |
不允許為null |
不允許為null |
Dictionary |
執行緒安全 |
ConcurrentHashMap |
不允許為null |
不允許為null |
AbstractMap |
鎖分段技術(JDK8:CAS) |
TreeMap |
不允許為null |
允許為null |
AbstractMap |
執行緒不安全 |
HashMap |
允許為null |
允許為null |
AbstractMap |
執行緒不安全 |