Java集合—HashMap底层原理
原文鏈接:最通俗易懂搞定HashMap的底層原理
HashMap的底層原理面試必考題。為什么面試官如此青睞這道題?HashMap里面涉及了很多的知識點,可以比較全面考察面試者的基本功,想要拿到一個好offer,這是一個邁不過的坎,接下來我用最通俗易懂的語言帶著大家揭開HashMap的神秘面紗
一、HashMap節點
HashMap是一個集合,鍵值對的集合,源碼中每個節點用Node<K,V>表示,Node是一個內部類,這里的key為鍵,value為值,next指向下一個元素,可以看出HashMap中的元素不是一個單純的鍵值對,還包含下一個元素的引用。
static class Node<K,V> implements Map.Entry<K,V> {final int hash;final K key;V value;Node<K,V> next;二、HashMap的數據結構
HashMap的數據結構為?數組+(鏈表或紅黑樹),為什么采用這種結構來存儲元素呢?數組的特點:查詢效率高,插入,刪除效率低。鏈表的特點:查詢效率低,插入刪除效率高。在HashMap底層使用數組加(鏈表或紅黑樹)的結構完美的解決了數組和鏈表的問題,使得查詢和插入,刪除的效率都很高。
三、HashMap存儲元素的過程
有這樣一段代碼:
HashMap<String,String> map = new HashMap<String,String>(); map.put("劉德華","張惠妹"); map.put("張學友","大S");現在我要把鍵值對 “劉德華”,”張惠妹”存入map,第一步計算出鍵“劉德華”的hashcode,該值用來定位要將這個元素存放到數組中的什么位置.什么是hashcode?在Object類中有一個方法:
public native int hashCode();該方法用native修飾,所以是一個本地方法,所謂本地方法就是非java代碼,這個代碼通常用c或c++寫成,在java中可以去調用它。調用這個方法會生成一個int型的整數,我們叫它哈希碼,哈希碼和調用它的對象地址和內容有關。哈希碼的特點是:對于同一個對象如果沒有被修改(使用equals比較返回true)那么無論何時它的hashcode值都是相同的,對于兩個對象如果他們的equals返回false,那么他們的hashcode值也有可能相等。明白了hashcode我們再來看元素如何通hashcode定位到要存儲在數組的哪里,通過hashcode值和數組長度取模我們可以得到元素存儲的下標。劉德華的hashcode為20977295 數組長度為 16則要存儲在數組索引為 20977295%16=1的地方
可以分兩種情況:
每個元素節點都有一個next屬性指向下一個節點,這里由數組結構變成了數組+鏈表結構,紅黑樹又是怎么回事呢?因為鏈表中元素太多的時候會影響查找效率,所以當鏈表的元素個數達到8的時候使用鏈表存儲就轉變成了使用紅黑樹存儲,原因就是紅黑樹是平衡二叉樹,在查找性能方面比鏈表要高.上述過程可以概括為下圖:
四、HashMap擴容
HashMap中有兩個重要的參數:初始容量大小和加載因子,初始容量大小是創建時給數組分配的容量大小,默認值為16,用數組容量大小乘以加載因子得到一個值,一旦數組中存儲的元素個數超過該值就會調用rehash方法將數組容量增加到原來的兩倍,專業術語叫做擴容。在做擴容的時候會生成一個新的數組,原來的所有數據需要重新計算哈希碼值重新分配到新的數組,所以擴容的操作非常消耗性能。創建HashMap時我們可以通過合理的設置初始容量大小來達到盡量少的擴容的目的。加載因子也可以設置,但是除非特殊情況不建議設置.
?
總結
以上是生活随笔為你收集整理的Java集合—HashMap底层原理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: web架构介绍
- 下一篇: Java集合—TreeMap底层原理