黄色网址大全免费-黄色网址你懂得-黄色网址你懂的-黄色网址有那些-免费超爽视频-免费大片黄国产在线观看

專注Java教育14年 全國咨詢/投訴熱線:400-8080-105
動力節點LOGO圖
始于2009,口口相傳的Java黃埔軍校
首頁 hot資訊 HashMap的底層結構和原理

HashMap的底層結構和原理

更新時間:2021-07-23 16:30:08 來源:動力節點 瀏覽1017次

HashMap是Java程序員使用頻率最高的用于映射(鍵值對)處理的數據類型。

Java為數據結構中的映射定義了一個接口java.util.Map,此接口主要有四個常用的實現類,分別是HashMap、Hashtable、LinkedHashMap和TreeMap(還有ConcurrentHashMap),類繼承關系如下圖所示:

hashmap結構

HashMap最多只允許一條記錄的鍵為null,允許多條記錄的值為null。

LinkedHashMap是HashMap的一個子類,保存了記錄的插入順序,在用Iterator遍歷LinkedHashMap時,先得到的記錄肯定是先插入的,也可以在構造時帶參數,按照訪問次序排序。

TreeMap實現SortedMap接口,能夠把它保存的記錄根據鍵排序,默認是按鍵值的升序排序,也可以指定排序的比較器,當用Iterator遍歷TreeMap時,得到的記錄是排過序的。如果使用排序的映射,建議使用TreeMap。在使用TreeMap時,key必須實現Comparable接口或者在構造TreeMap傳入自定義的Comparator,否則會在運行時拋出java.lang.ClassCastException類型的異常。

Hashtable是遺留類,很多映射的常用功能與HashMap類似,不同的是它承自Dictionary類,并且是線程安全的,任一時間只有一個線程能寫Hashtable

從結構實現來講,HashMap是:數組+鏈表+紅黑樹(JDK1.8增加了紅黑樹部分)實現的,如下如所示。

HashMap數據底層具體存儲的是什么?這樣的存儲方式有什么優點呢?

從源碼可知,HashMap類中有一個非常重要的字段,就是Node[]table,即哈希桶數組。

Node是HashMap的一個內部類,實現了Map.Entry接口,本質是就是一個映射(鍵值對),除了K,V,還包含hash和next。

HashMap就是使用哈希表來存儲的。哈希表為解決沖突,采用鏈地址法來解決問題,鏈地址法,簡單來說,就是數組加鏈表的結合。在每個數組元素上都一個鏈表結構,當數據被Hash后,得到數組下標,把數據放在對應下標元素的鏈表上。

如果哈希桶數組很大,即使較差的Hash算法也會比較分散,如果哈希桶數組數組很小,即使好的Hash算法也會出現較多碰撞,所以就需要在空間成本和時間成本之間權衡,其實就是在根據實際情況確定哈希桶數組的大小,并在此基礎上設計好的hash算法減少Hash碰撞。那么通過什么方式來控制map使得Hash碰撞的概率又小,哈希桶數組(Node[]table)占用空間又少呢?答案就是好的Hash算法和擴容機制。

在理解Hash和擴容流程之前,我們得先了解下HashMap的幾個字段。從HashMap的默認構造函數源碼可知,構造函數就是對下面幾個字段進行初始化,源碼如下:

int threshold; // 所能容納的key-value對極限,超過這個數目就重新resize(擴容)
final float loadFactor; // 負載因子,默認的負載因子0.75是對空間和時間效率的一個平衡選擇,建議大家不要修改
int modCount; //記錄HashMap內部結構發生變化的次數
int size;  //實際存在的鍵值對數量

在HashMap中,哈希桶數組table的長度length大小必須為2的n次方.

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

HashMap的內部功能實現很多,本文主要從:

1.根據key獲取哈希桶數組索引位置

2.put方法的詳細執行

3.擴容過程三個具有代表性的點深入展開講解。

確定哈希桶數組索引位置

不管增加、刪除、查找鍵值對,定位到哈希桶數組的位置都是很關鍵的第一步。前面說過HashMap的數據結構是數組和鏈表的結合,所以我們當然希望這個HashMap里面的元素位置盡量分布均勻些,盡量使得每個位置上的元素數量只有一個,那么當我們用hash算法求得這個位置的時候,馬上就可以知道對應位置的元素就是我們要的,不用遍歷鏈表,大大優化了查詢的效率。

HashMap的Hash算法本質上就是三步:取key的hashCode值、高位運算、取模運算。

分析HashMap的put方法

hashmap結構

擴容機制

擴容(resize)就是重新計算容量,向HashMap對象里不停的添加元素,而HashMap對象內部的數組無法裝載更多的元素時,對象就需要擴大數組的長度,以便能裝入更多的元素。

這里就是使用一個容量更大的數組來代替已有的容量小的數組,transfer()方法將原有Entry數組的元素拷貝到新的Entry數組里。

HashMap中,如果key經過hash算法得出的數組索引位置全部不相同,即Hash算法非常好,那樣的話,getKey方法的時間復雜度就是O(1),如果Hash算法技術的結果碰撞非常多,假如Hash算極其差,所有的Hash算法結果得出的索引位置一樣,那樣所有的鍵值對都集中到一個桶中,或者在一個鏈表中,或者在一個紅黑樹中,時間復雜度分別為O(n)和O(lgn)。

小結

1.擴容是一個特別耗性能的操作,所以當程序員在使用HashMap的時候,估算map的大小,初始化的時候給一個大致的數值,避免map進行頻繁的擴容。

2.負載因子是可以修改的,也可以大于1,但是建議不要輕易修改,除非情況非常特殊。

3.HashMap是線程不安全的,不要在并發的環境中同時操作HashMap,建議使用ConcurrentHashMap。

4.JDK1.8引入紅黑樹大程度優化了HashMap的性能。

以上就是動力節點小編介紹的"HashMap的底層結構和原理",希望對大家有幫助,想了解更多可查看HashMap底層實現原理。動力節點在線學習教程,針對沒有任何Java基礎的讀者學習,讓你從入門到精通,主要介紹了一些Java基礎的核心知識,讓同學們更好更方便的學習和了解Java編程,感興趣的同學可以關注一下。

提交申請后,顧問老師會電話與您溝通安排學習

免費課程推薦 >>
技術文檔推薦 >>
主站蜘蛛池模板: 18成人免费观看视频 | 国产高清精品入口麻豆 | 插菊花综合 | 国产在线综合视频 | 亚洲人成在线播放网站岛国 | 亚洲人成网站在线观看播放动漫 | 中文字幕一区在线播放 | 成年美女黄网站色大免费观看软件 | 久久久男女野外野战 | 51自拍| 日韩精品免费看 | 艳妇乳肉豪妇荡乳 | 国产精品天天看 | 亚洲一级毛片免费看 | 久久99精品九九九久久婷婷 | 欧美综合精品 | 夜夜摸天天操 | 一级做a爰全过程免费视频毛片 | 国产高清视频网站 | 久久久久综合国产 | 手机看片日韩国产一区二区 | www.丝袜| 免费国产黄网站在线观看 | 午夜羞羞视频在线观看 | 天天干干 | 欧美亚洲综合在线 | 黄色一级片免费观看 | 91香蕉污| 日本欧美一区二区 | 琪琪色网 | 午夜视频免费 成人 | 69av导航| 日本资源在线 | 国产在线不卡免费播放 | 一级成人毛片 | 国产精品日本一区二区在线看 | 午夜小视频男女在线观看 | 大杳蕉伊人狼人久久一本线 | 99色吧| 久久精品九九亚洲精品天堂 | 韩国伦理剧在线观看 |