JDK1.8中對hashmap的優化

Java編程語言中,最基本的結構就是兩種,一個是數組,另一個是模擬指針(引用),全部的數據結構均可以用這兩個基本結構來構造的,HashMap也不例外。HashMap其實是一個「鏈表散列」的數據結構,即數組和鏈表的結構,可是在jdk1.8裏 
加入了紅黑樹的實現,當鏈表的長度大於8時,轉換爲紅黑樹的結構。java

這裏寫圖片描述

從上圖中能夠看出,Java中HashMap採用了鏈地址法。鏈地址法,簡單來講,就是數組加鏈表的結合。在每一個數組元素上都一個鏈表結構,當數據被Hash後,獲得數組下標,把數據放在對應下標元素的鏈表上。算法

*/
    static class Node<K,V> implements Map.Entry<K,V> { final int hash;//用於定位數組索引的位置 final K key; V value; Node<K,V> next;//鏈表的下一個Node Node(int hash, K key, V value, Node<K,V> next) { this.hash = hash; this.key = key; this.value = value; this.next = next; }

 

Node是HashMap的一個內部類,實現了Map.Entry接口,本質是就是一個映射(鍵值對)。編程

有時兩個key會定位到相同的位置,表示發生了Hash碰撞。固然Hash算法計算結果越分散均勻,Hash碰撞的機率就越小,map的存取效率就會越高。數組

HashMap類中有一個很是重要的字段,就是 Node[] table,即哈希桶數組,明顯它是一個Node的數組。若是哈希桶數組很大,即便較差的Hash算法也會比較分散,若是哈希桶數組數組很小,即便好的Hash算法也會出現較多碰撞,因此就須要在空間成本和時間成本之間權衡,其實就是在根據實際狀況肯定哈希桶數組的大小,並在此基礎上設計好的hash算法減小Hash碰撞。那麼經過什麼方式來控制map使得Hash碰撞的機率又小,哈希桶數組(Node[] table)佔用空間又少呢?答案就是好的Hash算法和擴容機制。數據結構

 

若是哈希桶數組很大,即便較差的Hash算法也會比較分散,若是哈希桶數組數組很小,即便好的Hash算法也會出現較多碰撞,因此就須要在空間成本和時間成本之間權衡,其實就是在根據實際狀況肯定哈希桶數組的大小,並在此基礎上設計好的hash算法減小Hash碰撞。編程語言

這裏存在一個問題,即便負載因子和Hash算法設計的再合理,也免不了會出現拉鍊過長的狀況,一旦出現拉鍊過長,則會嚴重影響HashMap的性能。因而,在JDK1.8版本中,對數據結構作了進一步的優化,引入了紅黑樹。而當鏈表長度太長(默認超過8)時,鏈表就轉換爲紅黑樹,利用紅黑樹快速增刪改查的特色提升HashMap的性能,其中會用到紅黑樹的插入、刪除、查找等算法性能

相關文章
相關標籤/搜索