TreeSet是基于红黑树实现的有序集合,通过Comparable或Comparator自动排序,底层复用TreeMap,时间复杂度O(log n),要求元素不可变且比较逻辑符合规范。

TreeSet 是 Java 集合框架中基于红黑树(Red-Black Tree)实现的有序集合,它能自动对元素进行排序。这种排序不是靠插入后调用 sort 方法完成的,而是在插入、查找、删除等操作过程中,由底层 TreeMap 实时维护元素的有序结构。
自然排序:依赖元素自身的 Comparable 接口
当 TreeSet 中的元素类型实现了 Comparable 接口(如 String、Integer、Date 等),TreeSet 会调用其 compareTo() 方法比较大小,从而决定节点在红黑树中的位置。
- 插入一个新元素时,TreeSet 从根节点开始,逐层比较
compareTo()返回值(负数、0、正数),决定向左子树、命中、还是右子树继续查找 - 红黑树在插入后自动调整结构(旋转 + 着色),保证树近似平衡,使查找/插入/删除时间复杂度稳定在 O(log n)
- 遍历 TreeSet(如用 for-each 或迭代器)时,实际是按红黑树的中序遍历顺序访问节点,天然得到升序结果
定制排序:通过 Comparator 构造 TreeSet
如果元素类未实现 Comparable,或你想改变默认排序逻辑(比如降序、按某字段排序),可传入 Comparator 实现:
- 构造时传入:
new TreeSet(Comparator.comparing(Person::getAge).reversed()) - Comparator 的 compare(a, b) 方法替代 compareTo(),决定 a 和 b 的相对顺序
- TreeSet 内部仍用该 compare 方法驱动红黑树的插入与查找,整个过程对用户透明
底层本质:复用 TreeMap,Key 即元素
TreeSet 并非独立实现排序逻辑,而是内部封装了一个 TreeMap,把每个要存入的元素作为 key,value 固定为一个空对象(PresetValue):
立即学习“Java免费学习笔记(深入)”;
- add(e) → map.put(e, PRESENT)
- iterator() → map.keySet().iterator()
- 所以 TreeSet 的排序能力完全继承自 TreeMap —— 而 TreeMap 的排序机制,就是基于 Comparable / Comparator + 红黑树的动态平衡
注意事项:元素不可变 & 比较逻辑一致性
为了维持红黑树结构稳定,必须确保用于比较的字段在插入后不发生影响顺序的修改:
- 若使用可变对象(如自定义 Person),且 Comparator 基于 age 字段,但插入后又修改了 age,会导致该对象在树中的位置“错乱”,后续 contains/remove 可能失效
- compareTo 或 compare 方法必须满足自反性、对称性、传递性、一致性;否则 TreeSet 行为不可预测(如重复元素判断出错、遍历跳过某些元素)
- null 元素不允许(除非显式使用允许 null 的 Comparator,但需自行处理,不推荐)


















