TreeMap 核心知识点与面试题解析

TreeMap 核心知识点与面试题解析

一、TreeMap 基础概念

TreeMap 是 Java 集合框架中基于 红黑树(Red-Black Tree) 实现的 Map,具有以下特点:

  • 有序性 :默认按 key 的自然顺序Comparable)或自定义顺序Comparator)排序。

  • 时间复杂度

    • 插入、删除、查找:O(log n)

    • 遍历(如 entrySet()):O(n)(中序遍历)

  • 线程不安全 :需用 Collections.synchronizedMap()ConcurrentSkipListMap 替代。


二、TreeMap 核心实现

1. 底层数据结构:红黑树

  • 红黑树特性

    • 每个节点是红色或黑色。

    • 根节点和叶子节点(NIL)是黑色。

    • 红色节点的子节点必须是黑色(不能连续红节点)。

    • 从任意节点到其叶子节点的路径上,黑色节点数相同(黑高平衡)。

  • 自平衡机制 :通过旋转(左旋/右旋)变色保持平衡。

2. 排序方式

  • 自然排序Comparable):

    java

    java 复制代码
    TreeMap<String, Integer> map = new TreeMap<>(); // 默认按 String 字典序

    自定义排序Comparator):

  • java

java 复制代码
TreeMap<Integer, String> map = new TreeMap<>((a, b) -> b - a); // 降序

三、高频面试题

1. TreeMap 和 HashMap 的区别?

对比项 TreeMap HashMap
底层结构 红黑树 数组 + 链表/红黑树
是否有序 是(按 key 排序) 否(无序)
时间复杂度 O(log n) O(1)(平均)
线程安全
允许 null key 取决于 Comparator 允许(但只能有一个)

2. TreeMap 如何保证有序?

  • 红黑树的中序遍历(左-根-右)会按 key 的顺序输出。

  • 依赖 ComparableComparator 定义排序规则。

3. TreeMap 的 put() 方法流程?

  1. 如果红黑树为空,直接插入为根节点(黑色)。

  2. 按 Comparator 或 Comparable 查找插入位置。

  3. 插入新节点(默认为红色)。

  4. 平衡调整(可能涉及变色和旋转):

    • 如果父节点是红色:

      • 检查叔叔节点:

        • 叔叔是红色 → 变色(父、叔变黑,祖父变红)。

        • 叔叔是黑色 → 旋转 + 变色(左旋/右旋)。

4. 如何实现自定义排序?

java

java 复制代码
// 按 value 排序(需转为 List 再排序)
List<Map.Entry<String, Integer>> list = new ArrayList<>(map.entrySet());
list.sort((a, b) -> a.getValue() - b.getValue());

// 或者使用 Comparator
TreeMap<String, Integer> customMap = new TreeMap<>((a, b) -> b.compareTo(a)); // 降序

5. TreeMap 的 ceilingKey() 和 floorKey() 方法作用?

  • ceilingKey(K key):返回 ≥ key 的最小 key(如没有,返回 null)。

  • floorKey(K key):返回 ≤ key 的最大 key(如没有,返回 null)。

java

java 复制代码
TreeMap<Integer, String> map = new TreeMap<>();
map.put(1, "A");
map.put(3, "B");
map.put(5, "C");

map.ceilingKey(2); // 3
map.floorKey(4);   // 3

6. TreeMap 为什么用红黑树而不用 AVL 树?

对比项 红黑树 AVL 树
平衡标准 黑高平衡(宽松) 严格高度平衡(左右子树高度差 ≤1)
插入/删除 最多 3 次旋转(O(1)) 可能需 O(log n) 次旋转
查询效率 O(log n),但常数项较大 更快(严格平衡)
适用场景 适合频繁修改(如 Java 集合) 适合高频查询(如数据库索引)

四、代码实战

1. 按 key 降序排列

java

java 复制代码
TreeMap<Integer, String> map = new TreeMap<>((a, b) -> b - a);
map.put(3, "C");
map.put(1, "A");
map.put(2, "B");

System.out.println(map); // {3=C, 2=B, 1=A}

2. 获取子映射(subMap)

java

java 复制代码
TreeMap<Integer, String> map = new TreeMap<>();
map.put(1, "A");
map.put(2, "B");
map.put(3, "C");
map.put(4, "D");

// 获取 [2, 4) 的子映射
SortedMap<Integer, String> subMap = map.subMap(2, 4);
System.out.println(subMap); // {2=B, 3=C}

五、总结

  • TreeMap 适用于需要有序 key 的场景(如范围查询、排序)。

  • 底层是红黑树,保证 O(log n) 的操作效率。

  • 面试重点

    • 红黑树原理

    • 与 HashMap 的区别

    • 排序方式(Comparable/Comparator)

    • 常用方法(ceilingKey, floorKey, subMap)

相关推荐
Timmer丿1 分钟前
kafka学习笔记(三、消费者Consumer使用教程——从指定位置消费)
java·笔记·学习·kafka
lifallen8 分钟前
Apache Paimon:存储结构、写入及其源码分析
java·大数据·数据仓库·sql·flink·database
召田最帅boy19 分钟前
基于URL弹窗的图片链接生成功能技术实现
android·java·javascript
.似水27 分钟前
Python PyMySQL
开发语言·python
Code哈哈笑40 分钟前
【基于SpringBoot的图书购买系统】操作Jedis对图书图书的增-删-改:从设计到实战的全栈开发指南
java·spring boot·后端·spring·交互·jedis
珹洺43 分钟前
计算机操作系统(十四)互斥锁,信号量机制与整型信号量
java·redis·缓存
不会飞的鲨鱼43 分钟前
【QQ音乐】sign签名| data参数 | AES-GCM加密 | webpack(上)
开发语言·javascript·webpack
蓝色的猴子1 小时前
JUC 包
java
IDRSolutions_CN1 小时前
如何用命令行将 PDF 表格转换为 HTML 表格
java·经验分享·pdf·软件工程·团队开发
Java初学者小白1 小时前
秋招Day10 - JVM - 内存管理
java