详解集合之HashMap——HashMap内部结构,自动扩容机制,为什么需要重写hashcode和equals方法
HashMap底層實現是一個鍵值對Node數組,而Node實現了鍵值對Map.Entry接口
HashMap類繼承結構圖
?
?
1. HashMap對象的創建
1.1 默認的構造方法——只指定自動擴容時的加載因子loadFactor
?
1.2 對初始容量或加載因子設定的構造方法
通過tableSizeFor源碼分析,我們知道如果傳入參數是2的次方,比如1,2,4,8...,那么最終的返回值就是本身;如果不是,那么返回的是大于參數值,且最接近參數值的2的次方。如9,返回的是16,15返回的也是16。所以我們總結tableSizeFor方法的作用就是得到大于原始值的最小的2的次方。
?
1.3 傳入Map對象的構造方法
?
總結:HashMap的構造方法主要就是對threshold和loadFactor屬性賦值;但是我們發現只有默認構造方法沒有對threshold屬性賦值,而且類中有個常量屬性DEFAULT_INITIAL_CAPACITY,這里先記住,后面會有用。
?
2. HashMap添加元素
2.1 Map添加元素使用的是put方法,參數是key和value。內部調用putVal方法,參數是key的hash值,key,value,false,以及true,記住這些參數,后面分析putVal方法需要使用。
2.2 putVal源碼分析
2.3 總結:不考慮特殊情況以及數值超界,添加元素的邏輯為:根據key的hashcode簡單變形得到hash值,然后將該hash值映射到哈希表的索引。判斷該索引是否為null,為null,則使用信息創建新節點;不為null則判斷該索引的第一個節點是否和當前要添加節點的hash值以及==或equals相等,相等更新該節點的值即可。如果沒找到則判斷當前索引是否已經轉為紅黑樹(轉為樹的條件是哈希表數組大小大于等于64,并且單鏈表節點數大于等于8),如果是紅黑樹,則使用紅黑樹的節點添加方法;如果不是,則一直比對當前節點鏈表,找到更新值,找不到添加至尾部。所以我們需要重寫hashcode方法和equals方法,不然自帶的hashcode比較的是內存地址。
?
3. HashMap通過key獲取元素
?
4. HashMap其它常用方法
4.1 keySet和values方法得到key集合和value集合,keySet和values是內部屬性。
?
4.2 remove方法移除某元素——先尋找再移除
4.3 clear方法清空
4.4 containsKey方法判斷是否包含key
4.5 containsValue方法判斷哈希表是否包含某個value,很費時間,少用。
?
5. HashSet。
5.1?HashSet構造方法內部實際使用HashMap對象。
5.2 數據存儲時,只記錄key,不記錄value而已,value使用內部的一個Object類型常量PRESENT。
?
總結
以上是生活随笔為你收集整理的详解集合之HashMap——HashMap内部结构,自动扩容机制,为什么需要重写hashcode和equals方法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 详解java集合之LinkedList—
- 下一篇: 集合之TreeMap源码分析,简单介绍什