一、 Map 家族的順序分流:無序 vs 插入序 vs 大小排序HashMap:完全無序。遍歷順序取決於 Hash 值分佈與陣列擴容後的桶位變化,無法保證順序穩定。LinkedHashMap:保證順序。在 HashMap 的基礎上額外維護一條全域雙向鏈結串列,可選擇「插入順序(Insertion-order)」或「存取順序(Access-order)」。TreeMap:大小排序(Sorted)。底層完全依賴紅黑樹(Red-Black Tree),根據 Key 的自然順序或傳入的 Comparator 進行排序,時間複雜度為穩定的 $O(\log N)$。
二、 LinkedHashMap 的底層架構與雙重結構
三、 實戰架構:利用 LinkedHashMap 實作 LRU 快取(Least Recently Used)
LRU(最近最少使用淘汰演算法)廣泛應用於系統快取設計。利用 LinkedHashMap 只要改寫一個鉤子方法(Hook Method)即可完成:
核心實作範例
public class LruCache<K, V> extends LinkedHashMap<K, V> {
private final int maxCapacity;
public LruCache(int maxCapacity) {
// 容量、負載因子、accessOrder 必須設為 true
super(maxCapacity, 0.75f, true);
this.maxCapacity = maxCapacity;
}
// 每次 put 元素後,HashMap 底層會呼叫此方法判斷是否需要移除最舊節點
@Override
protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
return size() > maxCapacity;
}
}
淘汰流程運作原理:
每次存取(get 或更新 put)現有元素時,節點自動移動至雙向鏈結的尾端(Tail,代表最新存取)。
插入新節點時,若元素總數超過 maxCapacity,removeEldestEntry() 回傳 true。
容器自動將位於雙向鏈結頭端(Head,代表最久未被存取的舊節點)徹底移除。
四、 TreeMap 的紅黑樹排序與契約限制
底層原理與特徵實作了 NavigableMap 與 SortedMap 介面,底層是一顆自平衡二元搜尋樹(紅黑樹)。查詢、新增、刪除操作的時間複雜度均為嚴格的 $O(\log N)$。提供強大的區間查詢能力:floorKey()、ceilingKey()、subMap() 等。
核心契約:比較器決定一切(不依賴 equals 與 hashCode)不使用 Hash:TreeMap 在判斷兩個 Key 是否相同時,完全不呼叫 equals() 或 hashCode(),而是依賴 Comparable.compareTo() 或傳入的 Comparator.compare()。
TreeMap 在使用自然排序時嚴禁使用 null 作為 Key,執行時會直接拋出 NullPointerException(因為呼叫 key.compareTo() 無法對 null 操作)。