Hash table based implementation of the Map interface. This implementation provides all of the optional map operations, and permits null values and the null key. (The HashMap class is roughly equivalent to Hashtable, except that it is unsynchronized and permits nulls.) This class makes no guarantees as to the order of the map; in particular, it does not guarantee that the order will remain constant over time.
基于Map接口實現、允許null鍵/值、非同步、不保證有序(比如插入的順序)、也不保證序不隨時間變化。
hash函數的實現
通過hash的方法,通過put和get存儲和獲取對象。存儲對象時,我們將K/V傳給put方法時,它調用hashCode計算hash從而得到bucket位置,進一步存儲,HashMap會根據當前bucket的占用情況自動調整容量(超過Load Facotr則resize為原來的2倍)。獲取對象時,我們將K傳給get,它調用hashCode計算hash從而得到bucket位置,并進一步調用equals()方法確定鍵值對。如果發生碰撞的時候,Hashmap通過鏈表將產生碰撞沖突的元素組織起來,在Java 8中,如果一個bucket中碰撞沖突的元素超過某個限制(默認是8),則使用紅黑樹來替換鏈表,從而提高速度。
put 函數的實現 思路
1,對key 的hashCode()做hash 然后再計算index
2,如果沒用碰撞直接放到bucket
3,如果碰撞了 ,以鏈表的形式存在buckets
4,如果碰撞導致鏈表過長 就把鏈表轉換成紅黑樹
5,如果節點已經存在就替換old value(保證key 的唯一性)
6, 如果bucket 滿了 (超過load factory * current capacity) 就resize
get 函數的實現
1,bucket 里的第一個節點 直接命中
2,如果有沖突 ,則通過key.equals(k) 去查找對應的entry
若為樹 則在樹種通過 key.equals(k) o(logn)
若為鏈表 ,則在鏈表中通過 key.equals(k) 查找 ,o(n)
hash的實現
在Java 1.8的實現中,是通過hashCode()的高16位異或低16位實現的:(h = k.hashCode()) ^ (h >>> 16),主要是從速度、功效、質量來考慮的,這么做可以在bucket的n比較小的時候,也能保證考慮到高低bit都參與到hash的計算中,同時不會有太大的開銷。