arrays.sort 的稳定性取决于数组类型和 java 版本:基本类型数组使用双轴快排,天然不稳定;对象数组默认用 timsort,稳定,但依赖 comparator 实现正确;可通过装箱或 parallelsort 实现全程稳定。

Arrays.sort 的稳定性不能一概而论,它取决于你排序的是基本类型数组还是对象数组,也和 Java 版本、是否传 Comparator 有关。快速排序本身是不稳定的,而 Arrays.sort 对基本类型用的就是双轴快排——所以这部分天然不稳定;但对对象数组,它用的是 TimSort(稳定),这就形成了关键差异。
基本类型数组:双轴快排,不稳定是设计使然
int[]、double[]、char[] 等直接调用 Arrays.sort 时,底层走的是 Dual-Pivot Quicksort。这个算法虽比传统快排更高效(平均比较次数更少、缓存友好),但仍是不稳定的:
- 相同数值的元素可能在排序后交换位置,比如索引 2 和 5 都是 7,排完后 7 可能跑到前面,原来在前的反而靠后;
- 这种“不稳定”对纯数字通常无业务影响,但若你依赖原始顺序(例如按输入顺序做二次分组),就会出问题;
- 没有绕过方式——基本类型数组无法传 Comparator,也不能强制切到 TimSort。
对象数组:TimSort 默认稳定,但 Comparator 写错会“假不稳定”
String[]、Integer[] 或自定义类数组(如 Person[])默认使用 TimSort,它是归并排序的增强版,天然稳定:
- 相等对象(compare 返回 0)的原始相对位置一定保留;
- 但如果你写的 Comparator 逻辑有缺陷,比如只比较 name 忽略 age,两个 name 相同但 age 不同的 Person 被判为“相等”,它们的顺序就可能被重排——这不是 TimSort 失效,而是业务语义上“不该算相等”;
- 只要 Comparator 的 equals 含义与 compare 一致(即 a.equals(b) ⇔ compare(a,b)==0),稳定性就有保障。
想全程稳定?有明确替代方案
如果你的场景要求绝对稳定(比如多字段分层排序、或与 JavaScript sort 行为对齐),可以这样做:
- 基本类型 → 装箱成 Integer[] 等引用类型,再用 Arrays.sort(arr, comparator),触发 TimSort;
- 对象数组 → 确保 Comparator 实现严谨,必要时用 Comparator.thenComparing() 补充次级排序字段;
- Java 8+ 还可考虑 Arrays.parallelSort():对基本类型也改用归并逻辑,稳定且支持并行,适合大数组(注意小数组反而有开销)。
别混淆:不稳定 ≠ 错误,也不等于不可预测
双轴快排的“不稳定”是确定性行为,不是 bug。它每次对同一数组排序结果一致(除非并发修改),只是不承诺保持相等元素原序。而 JavaScript 的 Array.prototype.sort 自 ES2019 起已强制稳定,这是语言规范层面的差异,不是实现强弱问题。











