什么是map
是一種鍵值(key-value)映射表的數據結構
實現類
- HashMap Map主要實現類 線程不安全 效率高 可存儲 null的key value
-
LinkedHashMap 保證在遍歷map時 可以按照添加的順序實現
在原有hashMap的基礎上 添加了一對指針 指向前一個元素 和 后一個元素
對於頻繁的遍歷操作 LinkedHashMap 執行效率 高於 HashMap -
底層結構: 數組 + 鏈表(JDK7及之前) 數組 + 鏈表 + 紅黑樹(JDK8)
-
- TreeMap 排序 遍歷
底層使用紅黑樹 - Hashtable 線程安全 效率低 不能存儲null的key value
- Properties 常用來處理配置文件 key value都是String類型
Map特點
- key 無序 不可重復 跟set類似 key所在的類 要重寫hashCode() 和 equals()方法 (HashMap舉例)
- value無序 但是可以重復 使用Collection來存儲所有value value所在的類需要重寫equals()方法
- 一個key-value構成了一個Entry對象
- Map中的entry:無序的 不可重復 使用Set去存儲所有的entry
HashMap實現原理
JDK7
HashMap map = new HashMap();
實例化后 底層創建了長度是16的一維數組Entry[] table
map.put(key1,value1);
首先 調用key1所在類的hashCode方法 此哈希值經過某種計算后 得到在數組的位置
如果該位置沒有數據 `map.put(key1,value1);`添加成功
如果該位置有數據(最少有一個數據的存在) 比較key1和其他數據的哈希值是否相同
如果不相同 `map.put(key1,value1);`添加成功 情況2
如果和某個數據key2-value2相同 則比較key1 所在類的equals(key2)方法
如果返回值為false `map.put(key1,value1);`添加成功 情況3
如果返回值為true value1的值替換value2
情況2 和 情況3 此時的key1-value1和已經存在的數據以鏈表的方式進行存儲
最后 在不斷的擴容過程中 默認擴充為原來數組長度的兩倍 將原來的數據 copy 過來
jdk8相比較於jdk7
new HashMap() 底層沒有創建一個長度 16的數組
底層數組是Node[] 不是Entry[]
首次調用Put方法 創建長度為16的數組
當數組上某一索引的元素以鏈表的形式存在的數據個數 > 8 且當前數組長度 > 64時
此索引位置上的存儲數據結構改為 `紅黑樹`存儲
重要常量
DEFAULT_INITIAL_CAPACITY
默認容量 16MAXIMUM_CAPACITY
最大容量 230DEFAULT_LOAD_FACTOR
HashMap默認加載因子 0.75fthreshold
臨界值 = 默認容量 * 加載因子TREEIFY_THRESHOLD
鏈表長度大於 此值時 轉化為 紅黑樹 8MIN_TREEIFY_CAPACITY
被轉化成紅黑樹最小數組大小 64