算法 Arrays.sort()函数自定义排序(Comparator 接口)
Arrays.sort()
的核心功能是对数组元素进行原地排序(即直接修改原数组),支持以下两种排序方式:
- 自然排序:适用于实现了
Comparable
接口的元素(如Integer
,String
,Date
等) - 自定义排序:通过传入
Comparator
接口的实现类,自定义排序规则
常见的重载形式:
// 自然排序(要求元素实现 Comparable 接口)
public static void sort(int[] a)
public static void sort(Object[] a)// 自定义排序(通过 Comparator 接口)
public static <T> void sort(T[] a, Comparator<? super T> c)// 对部分元素排序(fromIndex 到 toIndex-1)
public static void sort(int[] a, int fromIndex, int toIndex)
一、Comparator 接口的基本定义:
@FunctionalInterface
public interface Comparator<T> {// 比较两个对象,返回值决定顺序int compare(T o1, T o2);// 默认方法(Java 8+新增)default Comparator<T> reversed() { ... }default Comparator<T> thenComparing(Comparator<? super T> other) { ... }// 更多默认方法用于组合比较器
}
- compare 方法返回值:
- 负数:表示
o1
应排在o2
前面 - 0:表示
o1
和o2
相等 - 正数:表示
o1
应排在o2
后面
- 负数:表示
二、四种核心使用方式
1. 匿名内部类实现(最经典方式)
String[] names = {"Alice", "Bob", "Charlie", "David"};// 按字符串长度升序排序
Arrays.sort(names, new Comparator<String>() {@Overridepublic int compare(String s1, String s2) {return s1.length() - s2.length();}
});
// 排序后:["Bob", "Alice", "David", "Charlie"]
2. Lambda 表达式(Java 8 + 推荐方式)
// 按字符串长度降序
Arrays.sort(names, (s1, s2) -> s2.length() - s1.length());// 按字母倒序(忽略大小写)
Arrays.sort(names, (s1, s2) -> s2.compareToIgnoreCase(s1));
3. 方法引用
// 按字符串自然顺序排序(等同于 Comparator.naturalOrder())
Arrays.sort(names, String::compareTo);// 按整数升序排序
Integer[] nums = {5, 3, 8, 1};
Arrays.sort(nums, Integer::compare);
4. 使用预定义比较器(Java 8 + 内置方法)
// 自然顺序(升序)
Comparator<String> natural = Comparator.naturalOrder();// 逆序(降序)
Comparator<String> reversed = Comparator.reverseOrder();// 按字符串长度排序
Comparator<String> byLength = Comparator.comparingInt(String::length);// 使用示例
Arrays.sort(names, byLength.reversed()); // 按长度降序
以 实现的寻找距离原点最近的 k 个点的算法 为例:
- 输入:二维平面上的点坐标数组
points
(每个点用 [x,y] 表示),以及整数 k - 输出:距离原点 (0,0) 欧几里得距离最近的 k 个点
public int[][] kClosest(int[][] points, int k) {// 对points数组进行排序,自定义比较器按距离从小到大排列Arrays.sort(points, new Comparator<int[]>() {public int compare(int[] point1, int[] point2) {// 计算两个点到原点的距离平方差return (point1[0] * point1[0] + point1[1] * point1[1]) - (point2[0] * point2[0] + point2[1] * point2[1]);}});// 返回排序后的前k个元素return Arrays.copyOfRange(points, 0, k);
}
比较器 (Comparator) 的作用
比较器需要实现compare
方法,该方法接收两个参数:
point1
和point2
分别代表两个待比较的点(一维数组,长度为 2)- 返回值决定了两个元素的顺序:
- 负数:表示
point1
应该排在point2
前面 - 正数:表示
point1
应该排在point2
后面 - 0:表示两个元素相等
- 负数:表示
通过传入 Comparator
实例,可以对任意类型的数组定义排序规则,避免修改原类