怎么看出 Java 的 Comparator是升序还是降序

怎么看出 Java 的 Comparator是升序还是降序

背景

有时候看代码,遇到 Comparator 的代码,怎么判断得到的结果是升序还是降序呢?我要运行之后得多慢啊,有没有规律

结论

其实是有秘诀的, Comparator一般会返回 -1、1和0三种情况(或者其他负整数、正整数,不一定非得-1和1),只要记住返回-1不需要调换顺序即可(很显然返回1的时候需要调换)。只要记住结论的一半即可,不容易混淆

记住秘诀:1嘛,一般在C语言里头1表是true,true就是要换位置的意思,那返回-1就是不需要调换位置咯

下面是具体的实验,请认真看并理解,需要自行认真琢磨一下

实验

  • 例子1

    public static void main(String[] args) {
      List<Integer> list = new ArrayList<>();
      list.add(1);
      list.add(3);
      list.add(2);
      System.out.println("before: " + list);
    
      Collections.sort(list, new Comparator<Integer>() {
        @Override
        public int compare(Integer o1, Integer o2) {
          if (o1 < o2) {
            return -1;
          } else if (o1 > o2) {
            return 1;
          } else {
            return 0;
          }
        }
      });
      System.out.println("after: " + list);
    }
    

    请问,光看代码,你觉得得到的结果是从小到大还是从大到小?

    分析:o1 < o2 的时候返回了-1,即不需要调换位置,即到时候会按照从小到大(升序)返回。

    o1是第一个元素,o2是第二个,当第一个元素比第二个小的时候不需要调换顺序,那就说明元素跟相邻的元素比较如果前面的比后面的小就不需要两两交换顺序,最终造成的结果就是从小到大升序

  • 例子2

    这个例子加一些混淆,让你没法这么快识别,请做下这个练习

    public static void main(String[] args) {
      List<Integer> list = new ArrayList<>();
      list.add(1);
      list.add(3);
      list.add(2);
      System.out.println("before: " + list);
    
      Collections.sort(list, new Comparator<Integer>() {
        @Override
        public int compare(Integer o1, Integer o2) {
          return o1 - o2;
        }
      });
      System.out.println("after: " + list);
    }
    

    依然可以分析出 o1 < 02 的时候返回-1或其他负整数,返回-1和负整数等价,所以其实还是从小到大升序的。

    那如果 return o2 - o1 呢?这里更好的理解方式是要在脑里改写一下这个表达式为 return -(o1 - o2),说明当o1 > o2 的时候返回-1保持不变,按自然就是从大到小降序了。在脑里改写下表达式会比较好理解!!!总之你得让compare方法的第一个参数排在前面会比较好理解!!!

  • 例子3

    再整复杂一些,再做一题(省略了不重要的代码)

    @Override
    public int compare(Integer o1, Integer o2) {
      return o2.compareTo(o1);
    }
    

    这个怎么理解呢?其实这个 Integer的comapreTo方法是这样子的,a.compareTo(b) 当a和b的值相等时返回0,a<b时返回-1,a>b时返回1(非常直观,你就将comapareTo方法想象成减号)

    然后,表达式相当于 return o2 - o1,自然相当于 return -(o1 - o2),自然o1 > o2的时候得到负整数保持不变,于是是降序

  • 例子4

    不是直接比较元素,而是比较元素里的字段

    public static void main(String[] args) {
      List<Stu> list = new ArrayList<>();
      list.add(new Stu("Stone"));
      list.add(new Stu("Tom"));
      list.add(new Stu("Jack"));
      System.out.println("before: " + list);
    
      Collections.sort(list, new Comparator<Stu>() {
        @Override
        public int compare(Stu o1, Stu o2) {
          return o1.getName().compareTo(o2.getName());
        }
      });
      System.out.println("after: " + list);
    }
    

    不是直接比较Stu对象,而是比较Stu里的name字段(名字),名字是按照字典升序来排的,谁的name排在前则其代表的Stu就排在前。

    o1.getName().compareTo(o2.getName())的含义,对于String的compareTo方法,是按照字典顺序返回值的,如果在字典中排在后面则返回1,否则返回-1(API里解释是 Compares two strings lexicographically,即 按字典顺序比较两个字符串

  • 13
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值