HashMap究竟是如何工做的?java
爲何HashMap的key必須惟一?算法
如下論述這兩個問題:編程
HashMap數據結構:數據結構
{ index, //hashMap 位置索引 Key, // key 信息 Value, //value 信息 Node<K,V> //指向下一個節點 }
index 如何計算?code
求對應的key的hashcode 爲h 而後 :h & (length-1); 其中 length表明hashMap大小索引
在HashMap源碼中對應的代碼爲:圖片
/** * Returns index for hash code h. */ static int indexFor(int h, int length) { // assert Integer.bitCount(length) == 1 : "length must be a non-zero power of 2"; return h & (length-1); }
編程的一切理論都要實戰化纔有意義:直接上代碼ip
package map; import java.util.HashMap; import java.util.Map; /** * hashMap principle Test * @author SB * */ public class HashMapPrinciple { public static void main(String[] args) { Map<String,Integer> map = new HashMap<String,Integer>(); map.put("JONES", 99); map.put("CLARK", 90); map.put("KING", 100); map.put("BLAKE", 10); map.put("WARD", 99); map.put("SMITH", 10); map.put("FORD", 110); map.put("RICK", 110); map.put("SOW", 50); map.put("CARL", 80); map.put("WWW", 70); map.put("",20); map.put("",30); System.out.println("map size : " + map.size()) ; for(String m : map.keySet()){ System.out.println(" index : " + calcIndex(calcHashValue(m)) + " ,key:" + m +" , hashCode : " + calcHashValue(m) ); } } public static int calcHashValue(String originInfo){ return originInfo.hashCode(); } public static int calcIndex(int hashCode){ return hashCode & 15; // 15爲HashMap默認長度 16-1 } }
輸出結果爲:ci
map size : 12 index : 0 ,key: , hashCode : 0 index : 8 ,key:CARL , hashCode : 2061080 index : 15 ,key:RICK , hashCode : 2515167 index : 7 ,key:WWW , hashCode : 86391 index : 1 ,key:BLAKE , hashCode : 63281361 index : 12 ,key:WARD , hashCode : 2656892 index : 7 ,key:JONES , hashCode : 70771223 index : 11 ,key:SOW , hashCode : 82299 index : 1 ,key:CLARK , hashCode : 64205105 index : 3 ,key:SMITH , hashCode : 79018979 index : 11 ,key:FORD , hashCode : 2163899 index : 7 ,key:KING , hashCode : 2306967
對應的存儲圖像直觀化get
如今根據這個圖片信息來解釋開始的兩個問題:
HashMap採用紅黑樹算法(red black tree)存儲這個結構
當key值相同時,對應的hashcode也必定相同,index也相同,因此put靠後的會把put以前的覆蓋掉。好比本例中: index : 0 ,key: , hashCode : 0 的值爲30.
三、key 值容許爲空,爲空時 index = 0 ,hashcode = 0
當map.get(key)時,會首先找對應的index,再匹配對應的hashcode,匹配上之後,獲取對應值。
首先經過 key.hashcode() & length-1
獲取 index, 再匹配 hashcode,既能夠獲取值。
疑問點: red black tree 如何實現?