HashMap(HashSet)的實現
阿新 • • 發佈:2019-02-09
0. HashMap(TreeMAP)、HashSet、HashTable 的關係
HashMap 的底層則維護著
Node<K, V>[] table;
一個一維陣列用於快速訪問(只在初次使用時進行初始化,當需要擴容時,When allocated, length is always a power of two.)static class Node<K,V> implements Map.Entry<K,V> { final int hash; // 此處的 hash 相當於 bucket final K key; V value; Node<K,V> next; // 每個節點均連結著一個連結串列;
在呼叫 get 方法返回該 key 對應的 value 時,先根據 key 對應的 hash 找到 bucket
if ( (tab = table) != null && (n = tab.length) > 0 && (first = tab[(n - 1) & hash]) != null) { if (first.hash == hash && // always check first node ((k = first.key) == key || (key != null
HashMap 在解決衝突時,採用的是衝突連結串列(Separate chaining with linked lists)的方式;
- HashSet 與 HashMap 有著相同的實現,HashSet 底層維護著一個 HashMap 物件,通過介面卡模式是對 HashMap 的進一步封裝(限制)
- HashMap實現了Map介面,允許放入null元素,除該類未實現同步外,其餘跟Hashtable大致相同
- 與 TreeMap 相比,TreeMap 是有序的;
1. HashMap 的實現
- 有兩個引數可以影響HashMap的效能:初始容量(inital capacity)和負載係數(load factor,也叫裝填因子)。初始容量指定了初始table的大小,負載係數用來指定自動擴容的臨界值。
- 當entry的數量(size)超過capacity*load_factor時,容器將自動擴容並重新雜湊。
- hashCode() 與 equals() 方法:
- hashCode()方法決定了物件會被放到哪個bucket裡,當多個物件的雜湊值衝突時,equals()方法決定了這些物件是否是“同一個物件”
2. 雜湊(hash)的一些細節
如果 hashCode 是負數會怎樣?負索引可不是你想要的。因此,一個改進的雜湊公式會移出符號位(符號為同 0 相與),然後再用取模(即 %)運算子計算剩餘部分。
(123 & 0x7FFFFFFF) % 20 = 3
(456 & 0x7FFFFFFF) % 20 = 16