TreeSet插入后天然有序,因其底层基于红黑树,add()时按比较规则定位并保持平衡;存自定义对象需实现Comparable或传入Comparator;不允null;重复判断依赖比较结果而非equals;修改参与比较的字段后需先remove再add。

TreeSet 默认就是升序排列,只要元素实现了 Comparable 接口(如 Integer、String),或者你显式传入了 Comparator,它就会自动按顺序组织内部红黑树结构 —— 不需要手动排序,也不需要调用额外方法。
为什么 TreeSet 插入后天然有序?
它底层是基于红黑树(TreeMap)实现的,每次 add() 都会根据比较规则定位插入位置并保持平衡。这不是“插入后再排序”,而是“边插边建序”。所以遍历结果永远升序(除非你用了反向 Comparator)。
插入自定义对象时必须提供比较逻辑
如果存的是自己写的类(比如 Person),TreeSet 无法默认知道怎么比大小,否则会抛 ClassCastException 或 NullPointerException。
两种解决方式:
- 让类实现
Comparable接口,重写compareTo()方法(推荐用于自然序) - 构造
TreeSet时传入Comparator实例(适合临时/多维度排序)
例如:
分析 Java Spring Boot 后端 Controller 代码,自动生成 Markdown 格式的接口文档。当用户说“生成 Java 接口文档”、“生成 API 文档”、“从 Spring 代码生成文档”时触发。
TreeSet<person> set = new TreeSet((a, b) -> Integer.compare(a.age, b.age));</person>
注意 null 和重复元素的处理
TreeSet 不允许 null 元素(除非你用的 Comparator 显式支持 null,但 JDK 自带的不支持),否则 add(null) 直接抛 NullPointerException。
重复判断依赖 compareTo() == 0 或 compare() == 0,不是 equals() —— 所以务必保证比较逻辑与 equals() 一致,否则会出现“能 add() 进去两个逻辑相等的对象”这种反直觉行为。
最常被忽略的一点:如果你改了对象的字段值,而这个字段参与了比较逻辑,那么该对象在 TreeSet 中的位置不会自动更新 —— 它已经“卡死”在红黑树某个节点上了。要安全修改,得先 remove() 再 add()。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










