treemap能自动排序因其底层采用红黑树,按key自然顺序或comparator规则维护节点;key需实现comparable或提供comparator,不支持null key,非线程安全。

TreeMap 为什么能自动排序
TreeMap 底层用的是红黑树(Red-Black Tree),不是哈希表,所以它天然按 key 的自然顺序(或自定义 Comparator)维护节点位置。插入、删除、查找都保持有序,不需要额外排序操作。
注意:key 类型必须实现 Comparable 接口(如 Integer、String),否则运行时抛 ClassCastException;或者构造时传入 Comparator 显式指定比较逻辑。
如何自定义 TreeMap 的排序规则
默认按 key 自然序升序,但多数实际场景需要定制,比如忽略大小写、按长度排序、或倒序。
- 倒序:用
Collections.reverseOrder(),如new TreeMap(Collections.reverseOrder()) - 忽略大小写:用
String.CASE_INSENSITIVE_ORDER - 按字符串长度:写匿名
Comparator,例如(s1, s2) -> Integer.compare(s1.length(), s2.length()) - 复合条件:先按长度,长度相同时按字典序,用
thenComparing链式调用
TreeMap 和 LinkedHashMap 选哪个
两者都保持“某种顺序”,但语义完全不同:
立即学习“Java免费学习笔记(深入)”;
-
TreeMap是按key值大小排序(逻辑序),get/put时间复杂度是O(log n) -
LinkedHashMap是按插入/访问顺序(物理序),get/put是O(1),但不提供基于值的范围查询(比如 “所有 key > 100 的项”) - 如果只需要遍历时“和插入顺序一致”,选
LinkedHashMap;如果要二分查找、子映射(subMap)、首尾键(firstKey()/lastKey()),必须用TreeMap
常见陷阱:null key 和并发修改
TreeMap 不允许 null 作为 key(会抛 NullPointerException),哪怕你传了 Comparator —— 因为红黑树在比较时仍需调用 compare(null, x) 或 x.compareTo(null),而多数 Comparator 并未处理 null。
另外,TreeMap 不是线程安全的。多线程读写时,不能只靠 Collections.synchronizedMap() 包一层就完事——它的迭代器仍可能抛 ConcurrentModificationException。真要并发使用,优先考虑 ConcurrentSkipListMap,它也是有序的,且支持高并发。
真正容易被忽略的是:TreeMap 的 entrySet() 迭代器返回的 Map.Entry 是可变的(setValue() 有效),但改 value 不影响树结构;而改 key 就会破坏排序,所以没有 setKey() 方法。










