1. 程式人生 > >HashMap實現原理

HashMap實現原理

一個 ash img 方法 shm 步長 初始 2的n次冪 http

HashMap的數據結構是數組+單向鏈表,數組裏面存儲就是鏈表的Head節點,鏈表節點存儲的是我們put進去的key/value。

技術分享

如果要實現HashMap,主要有三個重要的功能點:

1.初始化,也就是HashMap的構造方法

在初始化的時候要給數組的大小一個默認值,也就是常說的桶數量,當然這個值是可以指定的,缺省是通過HashMap的屬性來確定的

static final int DEFAULT_INITIAL_CAPACITY = 16;

對於HashMap中桶數量的值必須是2的N次冪,而且這個是HashMap強制規定的。這樣做的原因就是因為計算機進行2次冪的運算是非常高效的,僅通過位移操作就可以完成2的N次冪的運算。

2.put(K key, V Value)方法

通過key來計算一個hash值,這個值就是數組的index,get(index)來獲取鏈表的Head節點,如果沒有Head節點,就把當前key/value創建一個節點作為Head節點;通過更新或者插入新節點來將數據存儲起來。

如果數據量很大,造成鏈表很長,對數據的讀取有很大的性能影響,因此我們可以擴大數組的大小,也就是增加桶的數量。增加桶數量後要將原來的復制新的結構裏面,這個過程就是我們常說的rehash過程,很耗性能,這也是沒辦法的事,犧牲寫性能來換取都性能。

我們常說HashMap是非線程安全的,就是在多線程中使用HashMap,rehash會造成鏈表死循環,導致不可用。

那麽就有兩個問題

A.什麽時候擴容

HashMap默認初始容量16,加載因子0.75,也就是說最多能放16*0.75=12個元素,當put第13個時,HashMap將發生rehash,rehash的一系列處理比較影響性能,所以當我們需要向HashMap存放較多元素時,最好在初始化的時候指定合適的初始容量和加載因子,否則HashMap默認只能存12個元素,將會發生多次rehash操作。

B.怎麽擴容,或者說擴容的步長是多少

HashMap在擴容時,新數組的容量將是原來的2倍。

3.get(Object key)方法

通過key來計算一個hash值,這個值就是數組的index,get(index)來獲取鏈表的Head節點。利用Head節點遍歷這個鏈表,根據比較key的hash值以及key的數值是否相等(註意要用equals方法),從而找出相應的value,沒有則返回null。

HashMap實現原理