TreeMap适合需键自动排序的场景,基于红黑树实现O(log n)操作,支持floorKey/ceilingKey范围查询(需判null)、subMap子视图及自定义Comparator;不支持并发写入,高并发应选ConcurrentSkipListMap。

TreeMap 适合需要自动排序的键值对场景
TreeMap 的核心价值是维护键的自然顺序(或自定义比较器顺序),插入、删除、查找都基于红黑树实现,时间复杂度稳定在 O(log n)。它不适合高频随机写入+无序遍历的场景,但凡你关心“按字母、数字、时间先后顺序访问键”,或者需要快速拿到最小/最大键、前驱/后继键,TreeMap 就比 HashMap 更合适。
用 floorKey()、ceilingKey() 做范围查询时别漏掉 null 判断
这些方法在找不到匹配键时返回 null,不是抛异常——这是容易踩坑的地方。比如查“小于等于某个时间戳的最新配置”,如果用 treeMap.floorKey(timestamp) 却没判空,后续直接解包就会触发 NullPointerException。
常见使用模式:
- 查最近的下界:
treeMap.floorKey(key)(≤ key 的最大键) - 查最近的上界:
treeMap.ceilingKey(key)(≥ key 的最小键) - 取子视图(左闭右开):
treeMap.subMap(fromKey, toKey),注意两个边界都必须存在或满足比较逻辑,否则可能返回空 Map
构造时传 Comparator 比实现 Comparable 更灵活
如果你的键类型本身没实现 Comparable,或者想临时换一种排序逻辑(比如按字符串长度而非字典序),直接传 Comparator 是唯一选择。例如:
立即学习“Java免费学习笔记(深入)”;
TreeMapmap = new TreeMap<>((a, b) -> Integer.compare(a.length(), b.length()));
注意:一旦用了自定义 Comparator,就不能再往里 put null 键(会抛 NullPointerException),而自然排序的 TreeMap 允许 null 键(仅当 comparator 支持且未被调用时)。
并发环境下不能直接用 TreeMap,替代方案要看读写比例
TreeMap 本身不支持并发修改,多线程写入会破坏红黑树结构。如果只是读多写少,可用 Collections.synchronizedSortedMap(new TreeMap());但若写操作频繁,建议改用 ConcurrentSkipListMap——它也保持有序,且是真正线程安全的,底层用跳表实现,平均性能比同步包装的 TreeMap 更稳。
特别提醒:ConcurrentSkipListMap 不支持 subMap 返回的视图实时反映原 Map 的并发更新,它的子视图是弱一致性的,这点和 TreeMap 的强一致性不同。










