HashMap的內部結構與hash沖突


HashMap的內部結構

HashMap簡介:

  • HashMap繼承AbstractMap,AbstractMap實現Map接口
  • HashMap是線程不同步的,線程不安全的
  • HashMap可以把null作為條目的Key和value
  • HashMap性能好
  • 用作key的對象必須實現hashCode方法和equals方法
  • 不能保證鍵值對的順序
  • HashMap底層數據結構數組,鏈表,哈希表,紅黑樹

 

簡單來說,HashMap由數組+鏈表組成的,數組是HashMap的主體,鏈表則是主要為了解決哈希沖突而存在的,如果定位到的數組位置不含鏈表(當前entry的next指向null),那么對於查找,添加等操作很快,僅需一次尋址即可;如果定位到的數組包含鏈表,對於添加操作,其時間復雜度為O(n),首先遍歷鏈表,存在即覆蓋,否則新增;對於查找操作來講,仍需遍歷鏈表,然后通過key對象的equals方法逐一比對查找。所以,性能考慮,HashMap中的鏈表出現越少,性能才會越好。

 

 

*******end*********

 

看一下HashMap的put方法源碼

   public V put(K key, V value) { if (key == null) return putForNullKey(value); int hash = hash(key.hashCode()); int i = indexFor(hash, table.length); for (Entry<K,V> e = table[i]; e != null; e = e.next) { Object k; 
            if (e.hash == hash && ((k = e.key) == key || key.equals(k))) { V oldValue = e.value; e.value = value; return oldValue; } } modCount++; //快速失敗機制 addEntry(hash, key, value, i); return null; } 

判斷當前確定的索引位置是否存在相同hashcode和相同key的元素,如果存在相同的hashcode和相同的key的元素,那么新值覆蓋原來的舊值,並返回舊值。 如果存在相同的hashcode,那么他們確定的索引位置就相同,這時判斷他們的key是否相同,如果不相同,這時就是產生了hash沖突。 Hash沖突后,那么HashMap的單個bucket里存儲的不是一個 Entry,而是一個 Entry 鏈。 系統只能必須按順序遍歷每個 Entry,直到找到想搜索的 Entry 為止——如果恰好要搜索的 Entry 位於該 Entry 鏈的最末端(該 Entry 是最早放入該 bucket 中), 那系統必須循環到最后才能找到該元素。

 *******ps:本人為新手只是記錄自己的學習過程,如果有錯誤,希望大神指出,共同學習**************


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM