arrays.sort()是jdk深度优化的成熟方案:基本类型用双轴快排(含插入排序、三向切分、归并兜底),对象数组用自适应timsort;慢因多在装箱、误用comparator、边界错误等辅助环节。

直接用 Arrays.sort() 就行——它不是需要你手动调优的“半成品”,而是 JDK 已按数据特征深度优化的成熟方案。百万级排序慢,通常不在算法本身,而在误用、装箱、边界错误或 Comparator 写重了。
基本类型和对象数组,走的是两套完全不同的底层策略
Java 不会统一套用一种排序逻辑,而是自动匹配最优算法:
- int[]、long[]、double[] 等基本类型数组:用双轴快排(Dual-Pivot Quicksort)。它选两个基准值,把数组一次划为三段,减少比较次数;长度小于 47 的小数组自动切到插入排序;遇到大量重复元素时启用三向切分;递归过深时兜底切归并,避免最坏 O(n²)。
- String[]、Integer[]、自定义对象数组:用 TimSort。先扫描识别天然有序片段(Run),对小 Run 补足到最小长度(通常 32),再归并。它稳定、自适应,对部分有序、含重复、现实业务数据表现极佳,实际常接近 O(n)。
真正拖慢百万级排序的,往往是这些操作
排序本身很快,瓶颈常出在准备和使用环节:
- 对
int[]强加Comparator:编译直接报错。真要降序,别转成Integer[]再排——百万级装箱会触发大量 GC;推荐先Arrays.sort(arr)升序,再双指针原地翻转。 - 用
Arrays.sort(arr, from, to)时,to是右边界(不包含),写成to = arr.length才能排到最后一个元素;若只取 top-K,优先用PriorityQueue,比全量排序省时省内存。 - 对象数组的
Comparator要轻量:避免在compare()里解析字符串、调复杂 getter 或创建临时对象。例如按字符串长度排序,写Comparator.comparing(String::length),而不是每次调str.length()。
什么时候不该硬用 Arrays.sort?
它很强大,但不是万能解法:
-
纯整数且范围有限(如用户 ID 在 0~1000 万之间):计数排序可达 O(n),实测比
Arrays.sort()快 4–5 倍,内存也更省。 -
只要随机打乱(如抽奖):别用
sort配Math.random()比较器——结果不可靠且慢,直接用Collections.shuffle()(底层 Fisher-Yates)。 -
数据持续流入、需动态维护有序性:数组结构不适合,换成
TreeSet或带索引的跳表更合理。
别让辅助操作拖后腿
Arrays.sort() 是原地修改,不返回新数组。想保留原顺序,必须提前复制:int[] copy = Arrays.copyOf(arr, arr.length);对引用类型数组排序,只是重排引用地址,原对象内容没变——改排序后数组里的某个对象字段,原始数组对应位置的对象也会同步变化。
另外,Arrays.sort() 对 null 极其敏感。哪怕 String[] 中有一个 null,默认排序就会抛 NullPointerException;必须显式用 Comparator.nullsFirst(Comparator.naturalOrder()) 或提前过滤。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











