TreeSet适合持续插入并需动态有序查询的场景,Collections.sort()适合数据固定后一次性排序;前者基于红黑树,插入O(log n)、自动去重、内存高,后者基于优化快排,排序O(n log n)、速度快、内存低、允许重复。

TreeSet 插入时自动排序,适合频繁增删且需保持有序的场景;Collections.sort() 是对已有 List 一次性排序,适合数据基本固定、仅需排序一次的情况。两者适用前提不同,不能简单比“谁更快”,关键看使用模式。
TreeSet 的排序机制与性能特点
TreeSet 底层基于红黑树(自平衡二叉搜索树),每次 add() 都会按自然顺序或比较器插入到正确位置,保证集合始终有序。时间复杂度为 O(log n) 每次插入,n 是当前元素个数。
- 插入 10 万个元素:总时间约 O(n log n),但常数较大,因涉及树结构调整、节点创建等开销
- 不支持重复元素,自动去重,若业务需要保留重复项则不可用
- 获取首/尾元素(first()/last())或子集(subSet())是 O(log n) 或 O(1),查询效率高
- 内存占用略高,每个元素对应一个树节点对象
Collections.sort() 的排序机制与性能特点
Collections.sort() 要求传入 ArrayList 或其他支持随机访问的 List,底层调用 Arrays.sort(),对数组进行双轴快排(小数组用插入排序,大数组用 TimSort 的变种)。整体时间复杂度为 O(n log n),但实际运行极快,JVM 高度优化,缓存友好。
- 只在调用时排序一次,后续访问仍是普通 List,无额外维护成本
- 允许重复元素,不改变原集合结构,适合已加载完数据再排序的场景
- 排序后若再添加新元素,不会自动维持顺序,需手动插入或重新 sort()
- 空间开销小,复用原数组,无额外节点对象
典型场景对比建议
选 TreeSet 当:
- 数据持续流入(如实时日志流按时间排序),需边加边查最值或范围
- 频繁执行 ceiling()/floor()/headSet() 等有序操作
- 天然需要去重 + 有序,比如用户活跃时段去重统计
选 Collections.sort() 当:
- 数据一次性读取完毕(如从 DB 查出 10 万条记录),仅需展示前 N 条
- 后续主要做遍历或随机索引访问,极少查“第几小”或范围
- 对吞吐和内存敏感,且不需动态维护顺序
实测参考(粗略量级,JDK 17,i7-11800H)
对 10 万个随机 Integer 排序:
- TreeSet.add() 全部插入:约 18–22 ms
- ArrayList.add() + Collections.sort():约 6–9 ms
- 若还需后续 1000 次 range 查询(如 subSet),TreeSet 总耗时可能反超
注意:微基准测试易受 JIT 预热、GC、数据局部性影响,应结合真实调用链测量。

















