经常遇到需要对二维数组排序的情况,但是自己对这方面掌握的不太好。因此,在学习之后来做个笔记。也希望能够让看到的有缘人有所收获。
先贴代码,如何进行解释
int[][] arr = {{1, 3}, {2, 3}, {1, 5}, {4, 6}};
Arrays.sort(arr, new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
return o2[1] - o1[1];
}
});
System.out.println(Arrays.deepToString(arr));
在需要对二维数组进行排序时,可以使用Java的Comparator
来自定义排序规则。
在代码中可以看到,我们给Arrays.sort
函数传递了一个自定义的 Comparator 对象
作为参数。在这个 Comparator 对象中,我们重写了 compare
方法。
1. 那么,compare方法是如何定义排序方式的呢?定义规则是什么?
compare
方法是 Comparator
接口中定义的方法之一,用于比较两个对象的顺序。在Java中,它通常用于排序算法中,以确定元素的顺序。该方法有两个参数,分别是要比较的两个对象,通常被称为 o1
和 o2
。它返回一个整数值,表示 o1 和 o2 的比较结果。
如果返回值为负数,表示 o1 应该排在 o2 前面。
如果返回值为零,表示 o1 和 o2 相等,顺序不变。
如果返回值为正数,表示 o1 应该排在 o2 后面。
直接看规则可能比较晦涩,这里拿上面的代码进行一个举例。
- 假设当前o2[1] > o1[1],那么,函数返回的是正数。根据第三条规则,o1排在o2后面,那么此时就是降序。
- 假设当前o2[1] < o1[1],那么,函数返回的是负数。根据第一条规则,o1排在o2前面,那么此时也是降序。
我上面的举例说明了无论此时o2[1] 和 o1[1]谁大谁小,分析出来的结果都是降序排序。
2. 二维数组不变,我想改成根据第一维升序排序,代码应该是什么样子?
int[][] arr = {{1, 3}, {2, 3}, {1, 5}, {4, 6}};
Arrays.sort(arr, new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
return o1[0] - o2[0];
}
});
System.out.println(Arrays.deepToString(arr));
继续举例分析
- 假设当前o2[0] > o1[0],那么,函数返回的是负数。根据第一条规则,o1排在o2前面,那么此时就是升序。
- 同理,如果o2[0] < o1[0],那么,函数返回的是正数。根据第三条规则,o1排在o2后面,那么此时还是升序。
3. 到这里,是不是发现了什么规律?
在第一个案例中,参数的顺序是int[] o1, int[] o2
, 返回的值是o2[1] - o1[1]
,此时是降序
。
而在第二个案例中,参数的顺序还是int[] o1, int[] o2
,但此时返回的值变成了o1[0] - o2[0]
,排序方式则变成了升序
。
==是不是两者的顺序只要相同,就是升序。两者顺序相反,就是逆序。==我们可以做个实验验证一下。
int[][] arr = {{1, 3}, {2, 3}, {1, 5}, {4, 6}};
Arrays.sort(arr, new Comparator<int[]>() {
@Override
public int compare(int[] o2, int[] o1) {
if(o1[1] == o2[1]) {
return o1[0] - o2[0];
}
return o2[1] - o1[1];
}
});
System.out.println(Arrays.deepToString(arr));
我刻意将参数的名字也交换了顺序,此时成为了int[] o2, int[] o1
根据上面的猜测,这段代码的功能应该是根据第二维的数据进行升序排序,如果第二维数据相同,就根据第一维数据进行降序排序。
代码返回结果:
[[2, 3], [1, 3], [1, 5], [4, 6]]
可以看到,是符合我们的猜测。因此,我们可以直接根据返回值的相减顺序和参数的顺序进行判断,快速的写出升序或降序代码。
不过,这个技巧只能应用在返回值中有明显的减法操作。有时在返回值中减法不适用或者没有出现明显的减法,我们还是需要最根本的规则。要学会根据返回值的正负判断排序顺序
4. 代码简化
在上述案例中,我都是直接在参数中通过构造函数
建立了新的 Comparator 对象
。虽然代码看起来比较清晰,但不够简洁,可以用lambda表达式
替换。
替换后的代码为:
int[][] arr = {{1, 3}, {2, 3}, {1, 5}, {4, 6}};
Arrays.sort(arr, (o2, o1) -> {
if(o1[1] == o2[1]) {
return o1[0] - o2[0];
}
return o2[1] - o1[1];
});
System.out.println(Arrays.deepToString(arr));
上述内容是在我粗略了解之后写的笔记,可能有不周到或者错误的地方,欢迎大家一起讨论学习。