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)

相关推荐
www_pp_3 分钟前
# 基于SIFT的图像相似性检测与拼接:Python实现与解析
开发语言·python·计算机视觉
vortex521 分钟前
深入理解 Bash 中的 $‘...‘ 字符串语法糖
开发语言·bash·excel
海风极客44 分钟前
Go小技巧&易错点100例(二十八)
开发语言·后端·golang
yuanManGan1 小时前
C++入门小馆:继承
java·开发语言·c++
杨不易呀1 小时前
Java求职面试:Spring Boot与微服务的幽默探讨
java·spring boot·微服务·面试·求职
PythonicCC1 小时前
Python中有序序列容器的概念及其与可变性的关系
开发语言·windows·python
GGBondlctrl1 小时前
【Python】Python好玩的第三方库之二维码生成,操作xlsx文件,以及音频控制器
开发语言·python·第三方库·二维码生成·操作xlsx文件·操作音频文件
佩奇的技术笔记2 小时前
Java学习手册:SQL 优化技巧
java·sql
建筑转Java-张无忌2 小时前
在Java中,什么是checked exception(即compile-time exception、编译时异常)?
java·开发语言
动能小子ohhh2 小时前
Python中的客户端和服务端交互的基本内容
开发语言·python