Collections.sort() 自 JDK 7 起采用 TimSort 算法,兼顾稳定性、现实数据适应性与性能,支持自然排序和自定义 Comparator 排序,对有序或部分有序数据接近 O(n),最坏 O(n log n) 且常数更小。

Collections.sort() 是 Java 中最常用、最可靠的 List 排序工具,它不改变调用方式,却在 JDK 7 起悄然升级为 TimSort——一种兼顾速度、稳定性与现实数据特征的混合排序算法。它的强大不在于“多快”,而在于“怎么快得合理”:对已排好序或局部有序的数据能显著提速,同时严格保持相等元素的相对位置。
自然排序与自定义排序的两种用法
只要 List 元素实现了 Comparable 接口(如 String、Integer、LocalDate),就能直接调用 Collections.sort(list) 完成升序排列。这是最简洁的方式,依赖对象自身的 compareTo() 方法。
当需要按非自然规则排序时(比如降序、按字段、多条件),传入 Comparator 即可:
- 用 Lambda 表达式:
Collections.sort(people, (a, b) -> Integer.compare(a.age, b.age)) - 用方法引用链:
Collections.sort(people, Comparator.comparing(Person::getAge).thenComparing(Person::getName)) - 处理 null 值:
Comparator.nullsLast(Comparator.comparing(Person::getAge))
TimSort 的实际性能表现
不同于教科书上的归并排序,TimSort 会自动识别输入中的“有序段”(run)——比如连续升序或严格降序的子序列。对小段(≤32 元素)用二分插入排序预处理;再通过栈式归并合并,避免退化情况。这使得它在以下场景优势明显:
立即学习“Java免费学习笔记(深入)”;
- 完全有序或逆序列表:接近 O(n) 时间,远优于传统 O(n log n)
- 部分有序数据(如日志按时间追加后少量乱序):跳过大量无谓比较
- 含大量重复值:稳定排序保证业务逻辑一致性
最坏情况下仍是 O(n log n),但常数因子更小,实测比旧版 MergeSort 快 20%–50%。
影响排序效果的关键细节
TimSort 很聪明,但它的判断完全依赖 Comparator 的输出。一个写得不严谨的比较器,可能引发异常或错误结果:
- 避免整型溢出:
a - b改为Integer.compare(a, b) - 禁止 null 引用:用
Objects.compare(x, y, Comparator.nullsFirst(...)) - 确保逻辑自洽:传递性必须成立(若 a<b 且 b<c,则必有 a<c)
- 杜绝副作用:compare 方法里不能改对象状态、不能发 HTTP 请求、不能依赖随机数或当前时间
与其他排序方式的实用对比
Collections.sort() 修改原列表,适合明确需就地排序的场景;而 Stream.sorted() 返回新 List,适合函数式链式操作,但有额外对象开销。List.sort() 是 Java 8+ 新增的实例方法,语义同 Collections.sort(),只是调用更直接。
注意:它只支持 List,不适用于 Set 或 Map;对基本类型数组(如 int[])应使用 Arrays.sort(),底层是双轴快排,而非 TimSort。



















