TreeMap 和 LinkedHashMap原理介绍
🌳 一、TreeMap
1. 用法
import java.util.*;public class DemoTreeMap {public static void main(String[] args) {TreeMap<Integer, String> map = new TreeMap<>();map.put(3, "C");map.put(1, "A");map.put(2, "B");System.out.println(map); // {1=A, 2=B, 3=C}// 获取最小、最大 keySystem.out.println("最小key: " + map.firstKey()); // 1System.out.println("最大key: " + map.lastKey()); // 3}
}
👉 特点:
- 自动排序(默认升序,基于
key
) - 不允许 key 为 null(因为要比较)
- 底层是 红黑树
2. 原理图解
TreeMap 是一棵 红黑树,插入时会进行旋转和染色保证平衡。
例子:map.put(3,"C"), map.put(1,"A"), map.put(2,"B")
插入 3: 3(C)插入 1: 3(C)/1(A)插入 2: 2(B)/ \1(A) 3(C)
👉 插入后 TreeMap 会自动保持有序,最终是 {1=A, 2=B, 3=C}
。
🔗 二、LinkedHashMap
1. 用法
import java.util.*;public class DemoLinkedHashMap {public static void main(String[] args) {LinkedHashMap<Integer, String> map = new LinkedHashMap<>();map.put(3, "C");map.put(1, "A");map.put(2, "B");System.out.println(map); // {3=C, 1=A, 2=B}}
}
👉 特点:
- 保持 插入顺序
- 也可以配置为 访问顺序(常用于 LRU 缓存)
2. 原理图解
LinkedHashMap = HashMap + 双向链表
例子:插入顺序 3 -> 1 -> 2
哈希表结构 (快速查找):3 -> "C"1 -> "A"2 -> "B"双向链表结构 (保持顺序):Head <-> 3("C") <-> 1("A") <-> 2("B") <-> Tail
👉 因为有链表,所以遍历时顺序稳定。
📊 三、TreeMap vs LinkedHashMap 对比
特性 | TreeMap | LinkedHashMap |
---|---|---|
底层结构 | 红黑树(平衡二叉树) | HashMap + 双向链表 |
key 是否有序 | ✅ 自动排序(按 key 大小) | ✅ 插入顺序(或访问顺序) |
查找效率 | O(logN) | O(1) 平均 |
使用场景 | 需要排序,如排行榜、区间查询 | 保持插入顺序,如缓存、序列化 |
🔗 一、LinkedHashMap 内部结构(顺序保证版的 HashMap)
- 继承关系
public class LinkedHashMap<K,V>extends HashMap<K,V>implements Map<K,V>
👉 它完全基于 HashMap,只是在 Node 上增加了 before / after 两个指针,形成一个 双向链表,保证遍历时的顺序。
- 内部节点结构
static class Entry<K,V> extends HashMap.Node<K,V> {Entry<K,V> before, after; // 前驱和后继
}
结构示意:
table 哈希桶:table[0] -> Entry1table[1] -> Entry2table[2] -> Entry3双向链表(插入顺序/访问顺序):Head <-> Entry1 <-> Entry2 <-> Entry3 <-> Tail
- 特点
默认维护 插入顺序。
通过 accessOrder = true 可维护 访问顺序(最经典场景是 LRU 缓存)。
查询效率和 HashMap 一样 O(1),但是遍历时有序。
额外的内存消耗:链表指针。
🌳 二、TreeMap 内部结构(有序集合)
- 底层实现
TreeMap 是基于 红黑树(自平衡二叉搜索树)。
所有键都会按 自然顺序(Comparable) 或者 自定义 Comparator 排序。
- 节点结构
static final class Entry<K,V> implements Map.Entry<K,V> {K key;V value;Entry<K,V> left;Entry<K,V> right;Entry<K,V> parent;boolean color; // 红 / 黑
}
- 树形结构示例
假设插入 50, 30, 70, 20, 40:50(黑)/ \30(红) 70(红)/ \
20(黑) 40(黑)
👉 红黑树保证了 平衡性,查找、插入、删除的复杂度都是 O(logN)。
- 特点
有序性:天然支持按 key 排序。
区间查询:subMap, headMap, tailMap。
查找效率比 HashMap 差(O(logN) vs O(1)),但是有序特性是它的最大价值。
⚡ 三者对比:HashMap vs LinkedHashMap vs TreeMap
特性 | HashMap | LinkedHashMap | TreeMap |
---|---|---|---|
底层结构 | 数组 + 链表 + 红黑树(冲突时树化) | HashMap + 双向链表 | 红黑树 |
Key 顺序 | 无序 插入顺序 / 访问顺序 | 排序 | (升序 / 自定义 Comparator) |
查询复杂度 | O(1) 平均 | O(1)平均 | O(logN) |
插入复杂度 | O(1) 平均 | O(1) 平均(多维护链表) | O(logN) |
内存开销 | 少 | 较多(额外链表指针) | 较多(红黑树节点结构) |
典型场景 | 快速查找,不关心顺序 | LRU 缓存、日志有序输出 | 排行榜、区间查询、排序集合 |
🎨 总结图示
TreeMap (红黑树):2/ \1 3LinkedHashMap (链表):Head <-> 3 <-> 1 <-> 2 <-> Tail
- 想要 排序 👉 用
TreeMap
- 想要 顺序一致 👉 用
LinkedHashMap
- 想要 最快的查找 👉 用
HashMap