Map家族
1、頂層接口:Map<K,V>
-
實現:定義了 鍵值對的存儲 的抽象接口
- 常用方法:put() get() remove() containsKey() entrySet() keySet() values()
- 底層:只是規範,並不關心具體數據結構
- 應用:統一API,讓不同實現類有相同的使用方式
- 作用:抽象層,解耦調用方與實現類
2、HashMap
-
底層:
- jdk 1.7:數組+鏈表 jdk1.8+:數組+鏈表+紅黑樹(後鏈表長度 > 8 時轉為紅黑樹)
- 哈希函數:對hashCode做擾動運算,減少衝突
- 擴容:容量翻倍,重新hash
- 應用:緩存、統計、配置存儲
- 作用:O(1)平均查找、插入效率 無序查找,效率優先
-
業務場景(最常用的):
- 緩存:存儲一些臨時數據,比如一個用户的ID和用户信息的映射
Map<Integer, User> userCache = new HashMap(); userCache.put(1001, new User("wjj"));- 快速查找:比如統計單詞出現的次數
Map<String, Integer> countMap = HashMap<>(); // 統計 apple 出現的次數,出現就+1,否則放入1- 配置存儲:存儲一些配置項,比如數據庫連接參數(key=配置名,value=值)
3、LinkedHashMap
- 底層:繼承HashMap,多了一個 雙向鏈表,保證插入順序或訪問順序
- 特點:有序(插入順序 或 LRU順序)
-
業務場景:
- LRU緩存(最常見):可以設置accessOrder = true ,自動把最近訪問的放到最後,淘汰最久沒有訪問的 (accessOrder 按照訪問順序排列 false就是按照插入順序)
LinkedHashMap<Integer, String> lruCache = new LinkedHashMap<>(16, 0.75f, true); // 第一個參數:初始容量 第二個:負載因子(當元素超過16*0.75=12時進行擴容) // 第三個參數:是否按照訪問順序排序- 需要順序輸出的情況:比如保存菜單項,按用户定義的順序展示
4、TreeMap
- 底層:紅黑樹(有序二叉查找樹)
- 特點:按照 key 排序(自然排序 or Comparator)。查找 / 插入O(logN)
-
業務場景:
- 排行榜:比如存儲用户分數,key = 分數,value = 用户,天然排序
TreeMap<Integer, String> rank = new TreeMap<>(); rank.put(100, "wjj"); rank.put(200, "jjw"); // TreeMap會自動進行排序- 範圍查詢:比如找“分數在80-100的所有學生”
SortedMap<Integer, String> sub = rank.subMap(80, 101); /* TreeMap就是實現了SortedMap接口的具體實現類 SortedMap是一個接口,規定 有序Map 應該支持的一些功能 1. subMap(fromKey, toKey) 獲取某個範圍的子視圖 2. headMap(toKey) 獲取比某個key小的所有映射 3. tailMap() 獲取比某個key大的所有映射 4. firstKey()、lastKey() 獲取最大、最小key */
5、ConcurrentHashMap
為什麼使用這個?
- HashMap線程不安全,多線程環境下會出現問題(eg:死循環、數據丟失)
- Hashtable雖然線程安全,但是因為對方加了全表鎖(synchronized),併發性能很差
- 底層:分段鎖(jdk7),CAS+synchronized(jdk8)
- 特點:高併發環境下使用,性能遠高於Hashtable,其迭代器是弱一致性,其他線程更改Map,不會拋異常
-
業務場景:
- 併發緩存:多線程同時讀寫緩存數據(用户session、token、臨時數據啥的)
ConcurrentHashMap<String, Object> cache = new ConcurrentHashMap<>(); cache.put("token", "xyz123");- 統計併發管理訪問量:比如電商系統中統計商品的訪問次數
- 存放共享資源:比如多個線程共享的用户session信息
6、Hashteble
- 底層:數組+鏈表
- 特點:線程安全(方法上加synchronized,全),不允許null key和null value
-
業務場景:
- 早期多線程程序:現在基本被ConcurrentHashMap替代
- 維護老項目會遇到,新開發基本用不上
7、WeakHashMap
- 底層:key用弱引用存儲,GC發現key沒有強引用時,會自動回收對應的entry
- 特點:適合做“臨時性緩存”
-
業務場景:
- 緩存場景:避免緩存導致內存泄露,比如class loader緩存(當key沒人引用時,GC會自動清理)
- 圖片緩存:android中用過,用於圖片對象的緩存
8、IdentityHashMap
- 底層:和HashMap類似,但key比較用 ==(地址比較) 而不是equals()
-
業務場景:
- 對象唯一性映射:比如序列化時,判斷一個對象是否已經被處理過
// 普通 HashMap 會認為兩個內容一樣的對象是同一個,但 IdentityHashMap 可以區分 String a = new String("abc"); String b = new String("abc"); Map<String, String> map = new IndentityHashMap<>(); map.put(a, "A"); map.put(b, "B"); System.out.println(map.size()) // 輸出2 而 HashMap 會輸出 1- 特殊框架實現:一般業務開發幾乎不用