1. 概述
在这篇简短的文章中,我们将对 Java 中的两个排序方法进行对比:Arrays.sort(Object[])
和 Arrays.sort(int[])
。
首先,我们会分别介绍这两个方法的实现原理和使用方式。然后通过性能测试,比较它们在实际运行中的效率差异。
2. Arrays.sort(Object[])
在继续之前,需要明确一点:Arrays.sort()
方法可以处理基本类型数组和引用类型数组。
而 Arrays.sort(Object[])
是专门用于处理引用类型的数组。
举个例子,我们有一个 Integer
对象数组:
Integer[] numbers = {5, 22, 10, 0};
我们可以直接调用:
Arrays.sort(numbers);
执行后,数组将按升序排列:
[0, 5, 10, 22]
这个方法内部使用的是 TimSort 算法,时间复杂度为 **O(n log n)**。简单来说,TimSort 是插入排序和归并排序的结合体。虽然效率不错,但在多数情况下,它还是比不上一些优化后的快速排序实现。
3. Arrays.sort(int[])
与之相对,Arrays.sort(int[])
是用于处理基本类型 int
数组的。
我们同样定义一个 int[]
数组:
int[] primitives = {5, 22, 10, 0};
然后调用排序方法:
Arrays.sort(primitives);
结果和前面一样:
[0, 5, 10, 22]
不过,它的底层实现使用的是 双轴快速排序(Dual-Pivot Quicksort)算法。从 JDK 10 开始,这种实现通常比传统的单轴快速排序更快。
该算法的平均时间复杂度同样是 **O(n log n)**,非常适合大多数排序场景。而且它是原地排序,不需要额外的存储空间。
⚠️ 但要注意,在最坏情况下,它的时间复杂度会退化为 **O(n²)**。
4. 性能对比
那么,哪个排序方法更快?我们先从理论上分析,再通过 JMH 实际测试验证。
4.1. 理论分析
通常来说,Arrays.sort(int[])
会比 Arrays.sort(Object[])
更快,主要原因如下:
- 算法差异:快速排序通常比 TimSort 更快
- 元素比较方式不同:
Arrays.sort(Object[])
需要调用对象的compareTo()
方法,这涉及到方法调用开销- 而
Arrays.sort(int[])
直接使用原生的<
、>
等操作符,是单字节码指令,效率更高
4.2. JMH 配置
为了验证理论,我们使用 JMH(Java Microbenchmark Harness) 来做性能测试。
测试类配置如下:
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@Measurement(batchSize = 100000, iterations = 10)
@Warmup(batchSize = 100000, iterations = 10)
public class ArraySortBenchmark {
}
说明:
- 使用平均时间模式(
Mode.AverageTime
) - 时间单位为毫秒(
TimeUnit.MILLISECONDS
) - 每轮测试执行 100000 次,共 10 轮,确保结果准确性
4.3. 测试代码
测试前,我们准备数据容器:
@State(Scope.Thread)
public static class Initialize {
Integer[] numbers = {-769214442, -1283881723, 1504158300, -1260321086, -1800976432, 1278262737,
1863224321, 1895424914, 2062768552, -1051922993, 751605209, -1500919212, 2094856518,
-1014488489, -931226326, -1677121986, -2080561705, 562424208, -1233745158, 41308167 };
int[] primitives = {-769214442, -1283881723, 1504158300, -1260321086, -1800976432, 1278262737,
1863224321, 1895424914, 2062768552, -1051922993, 751605209, -1500919212, 2094856518,
-1014488489, -931226326, -1677121986, -2080561705, 562424208, -1233745158, 41308167};
}
测试方法如下:
@Benchmark
public Integer[] benchmarkArraysIntegerSort(ArraySortBenchmark.Initialize state) {
Arrays.sort(state.numbers);
return state.numbers;
}
@Benchmark
public int[] benchmarkArraysIntSort(ArraySortBenchmark.Initialize state) {
Arrays.sort(state.primitives);
return state.primitives;
}
4.4. 测试结果
运行测试后,结果如下:
Benchmark Mode Cnt Score Error Units
benchmarkArraysIntSort avgt 10 1.095 ± 0.022 ms/op
benchmarkArraysIntegerSort avgt 10 3.858 ± 0.060 ms/op
✅ 可以看到,Arrays.sort(int[])
明显优于 Arrays.sort(Object[])
,符合我们的理论分析。
当然,这只是在特定数据下的测试结果,实际使用中还需根据数据规模、分布等进一步验证。
4.5. 为什么还要用 TimSort?
既然快速排序更快,那为什么 Arrays.sort(Object[])
不也用它呢?
❌ 因为快速排序是不稳定排序,而 Java 要求对对象数组排序时必须是稳定排序。
比如,对一组对象按某个字段排序,如果两个对象该字段值相同,它们的相对顺序不能改变。这种场景下,快速排序就不适用了。
5. 总结
本文对比了 Java 中的两种排序方式:
Arrays.sort(int[])
使用双轴快速排序,速度快,适用于基本类型Arrays.sort(Object[])
使用 TimSort,稳定但稍慢,适用于对象类型
通过 JMH 测试,我们验证了基本类型排序的性能优势。
如需查看完整代码,可前往 GitHub 项目地址。