Arrays.sort底层是动态算法选择机制:基本类型用DualPivotQuicksort(小数组插排、中等数组双轴快排、大或深度超限则归并兜底),对象数组固定用稳定Timsort,类型绑定硬编码不可切换。

Arrays.sort 的底层逻辑不是“二选一”,而是根据数组类型、长度、结构特征动态选择最合适的算法——双轴快排(DualPivotQuicksort)和归并排序(Timsort)各司其职,互不替代。
基本类型走双轴快排,但会兜底归并
对 int[]、long[] 等基本类型数组,Arrays.sort() 默认调用 DualPivotQuicksort.sort()。它不是纯快排,而是一套带多重保护机制的混合策略:
- 长度 ≤ 47:直接用插入排序(无递归开销,缓存友好)
- 长度在 48–286 之间:启用双轴快排,五取样选 pivot(e1–e5),三向切分处理重复值
- 长度 > 286:先检测数组局部有序性(比如已有一段升序 run),若发现足够多连续有序段(run 数 ≤ 67),就切换为归并排序(本质是 Timsort 的变体);否则继续双轴快排
- 递归深度超限(约 2×log₂n):强制退回到归并排序,避免快排最坏 O(n²) 场景
对象数组默认用 Timsort,不是传统归并
对 Object[](包括自定义类数组),Arrays.sort(Object[]) 调用的是 TimSort.sort(),它虽基于归并思想,但做了关键增强:
- 先扫描数组,识别天然升序/降序段(称为 run),把降序段原地反转,统一成升序 run
- 对短 run 补齐至最小长度(minrun ≈ 32),再两两归并
- 全程保持稳定性:相等对象的原始相对位置不会改变
- 空间复杂度 O(n),但实际运行中常利用已有有序性,比朴素归并快得多
为什么不能混用?类型绑定是硬编码的
Java 没有提供“让对象数组也走双轴快排”的开关,因为算法入口按参数类型静态分发:
-
sort(int[])→DualPivotQuicksort.sort(int[],...) -
sort(Object[])→TimSort.sort(Object[],...) -
sort(T[], Comparator)→ 同样走 TimSort(JDK 8+),哪怕 comparator 只比一个 int 字段
这种设计不是偷懒,而是权衡:基本类型无需稳定,双轴快排原地、快、省空间;对象排序默认要稳定,Timsort 在真实数据(部分有序)上表现更鲁棒。
怎么看源码?重点盯这几个类
打开 JDK 源码,直接定位:
-
java.util.Arrays:入口方法,按重载签名分发到不同实现 -
java.util.DualPivotQuicksort:int/long/float/double 等专用实现,含 pivot 选取、三向分区、阈值判断 -
java.util.TimSort:对象数组排序核心,含 run 探测、minrun 计算、归并栈管理 -
java.util.ComparableTimSort(旧版)或TimSort(新版):Comparator 版本复用同一套逻辑
不必逐行读完,先看每个 sort 方法开头的长度判断和分支注释,就能理清决策路径。


















