Java數據結構之004--HashMap

數組和鏈表都是存儲一個對象,HashMap 存儲數據是以 一對數據來存儲,即鍵值對【key(對象)---->value(對象)】。算法

JDK1.8版本以前,HashMap的實現: 數組 + 鏈表;數組

JDK1.8版本以後,HashMap的實現: 數組 + 鏈表 / 二叉樹(紅黒樹);安全

數組的默認大小是16,加載因子【DEFAULT_LOAD_FACTOR】默認值是0.75f,表示當數組容量達到75%,數組會被從新擴充。數組的最大容量是整數最大值的一半。數據結構

 

HashMap存儲數據結構中鏈表與二叉樹的轉化條件:  是鍵值對的總數大於64,且性能

a.在擴容時,當哈希表中數組同一個位置的鏈表長度大於8時(閥值),那麼會把鏈表轉換成紅黑樹,來提升查詢效率;spa

b.在擴容時,當哈希表中數組同一個位置的鏈表長度小於6時(閥值),那麼會把紅黑樹轉換成鏈表,來提升查詢效率。線程

閥值爲何是8 和 6? (防抖)減小鏈表與二叉樹之間的轉換頻率,避免影響性能。對象

 

哈希表:這個是由於存儲數據的方式被稱爲哈希(算法),Object類中hashCode方法是一個本地方法:表示此方法的具體實現是由 C、C++來實現的,哈希值()。內存

    同一個對象,咱們要保證在運行期hashCode值是相同的,若是不一樣那麼此對象在哈希表中會有內存泄露問題。ci

內存泄露:因爲對象在運行過程當中,hashCode不一樣,致使該對象在哈希表中沒法找到。

哈希表存儲數據的算法:經過計算key對象的hashCode值,來確認key對象在哈希表數組中的存儲位置,目的是爲了能夠經過計算hash值快速的查找對象。同一個對象,hashCode值相同,不一樣的對象,hashCode可能相同,由於整數是有限的。

使用hashCode計算對象的hash值:return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16)。

 

怎麼擴容?初始化大小?

a.在第一次put數據的時候初始化;

b.在put方法中實現,擴容算法是 oldCap << 1  表示乘於2;

c.每次擴容哈希表,會致使全部已存儲的對象從新計算哈希值,存儲到新的哈希表中(從新散列)。因此在hashMap中,對象所在的位置不保證永遠不變(無序),從新散列會致使從新計算全部對象,消耗性能,在可預知的狀況下,散列次數越少越好。

 

HashMap的優勢與缺點?

優勢:取值快,數據量越大越明顯;

缺點:線程不安全,避免頻繁散列(rehash)。合理的使用new HashMap<>(initialCapacity);初始容量,來減小散列。

相關文章
相關標籤/搜索