1. 程式人生 > >Map遍歷KeySet()和EntrySet的效能差異與原始碼解析

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

執行緒不安全

反例:由於HashMap的干擾,很多人認為ConcurrentHashMap是可以置入null值,而事實上,儲存null值時會丟擲NPE異常。