二维数组的自定义排序

经常遇到需要对二维数组排序的情况,但是自己对这方面掌握的不太好。因此,在学习之后来做个笔记。也希望能够让看到的有缘人有所收获。

先贴代码,如何进行解释

	  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中,它通常用于排序算法中,以确定元素的顺序。该方法有两个参数,分别是要比较的两个对象,通常被称为 o1o2。它返回一个整数值,表示 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));

上述内容是在我粗略了解之后写的笔记,可能有不周到或者错误的地方,欢迎大家一起讨论学习。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值