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:本人為新手只是記錄自己的學習過程,如果有錯誤,希望大神指出,共同學習**************