Arrays.sort()是“极速排序”,其核心在于JDK基于数组长度与数据分布自动选用插入排序、双枢轴快排或归并排序,并通过采样选枢轴、三指针划分及多重兜底机制实现高效稳定。

直接调用 Arrays.sort() 就是“极速排序”本身——它不需你手写算法,JDK 已根据数组长度、数据分布自动选用最优策略。核心不是“怎么快”,而是“为什么快”,关键就在双枢轴快排(DualPivotQuicksort)的分治逻辑和自适应优化。
基础类型排序只需一行,但背后有三层智能决策
对 int[]、double[] 等基本类型数组,调用方式极简:
-
Arrays.sort(arr)—— 默认升序,原地修改 -
Arrays.sort(arr, fromIndex, toIndex)—— 只排子区间,不创建新数组
真正让它“极速”的,是 JDK 内部的动态路径选择:
- 长度
- 长度 47–285:启用双枢轴快排主流程
- 长度 ≥ 286:先检测是否“基本有序”,若是则切到归并排序;否则继续双枢轴快排
双枢轴快排不是“两个快排”,而是三段并发划分
传统单轴快排选一个 pivot,把数组劈成“p1 ),一次性划出三段:
- 左段:(确定最小区间)
- 中段:≥ p1 且 ≤ p2(天然有序候选区)
- 右段:> p2(确定最大区间)
这带来两个实质加速点:
- 每轮划分减少一次比较:传统快排对每个元素至少比 1 次;双枢轴多数元素只需比 1–2 次即可归位
- 递归深度更浅:三段并行收缩,最坏情况退化概率显著低于单轴
理解 pivot 选取与边界指针协作机制
实际执行中,JDK 不简单取首尾作 pivot,而是采样 5 个位置(首、中、尾、¼、¾),取中位数为 p1、次中位数为 p2,避免极端数据打乱分区平衡。
三个核心指针协同推进:
- L:从左向右,标记“
- K:扫描指针,从 L 起向右遍历待处理区
- G:从右向左,标记“> p2”段的左边界
每次 K 遇到一个元素 x:
- 若 x
- 若 p1 ≤ x ≤ p2:K++(直接留在中段)
- 若 x > p2:交换 arr[K] 与 arr[G],G--(K 不增,下次再判新值)
这个过程确保三段边界严格收敛,无需额外空间,且每步都逼近最终位置。
不依赖运气,靠结构感知规避最坏性能
双枢轴快排仍属比较排序,理论最坏仍是 O(n²),但 JDK 实现做了三重加固:
- 当递归深度超过阈值(≈ 2×log₂n),强制切换到堆排序兜底
- 对重复元素高度集中的场景(如大量相同 int),内部会触发“三路划分”优化,把等于 p1/p2 的全归中段,避免无效递归
- 对已近似有序数组,如前述 ≥286 时触发归并分支,彻底绕开快排退化风险
所以你写的那行 Arrays.sort(arr),本质是启动了一个小型自适应排序引擎——你提供数据,它判断形状,分配算法,静默完成。










