• 怎么看出 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);
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21

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

      分析: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);
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15

      依然可以分析出 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);
      }
      
      • 1
      • 2
      • 3
      • 4

      这个怎么理解呢?其实这个 Integer的comapreTo方法是这样子的,a.compareTo(b) 当a和b的值相等时返回0,ab时返回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);
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15

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

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

  • 相关阅读:
    雅思 Band 7+ 预备课程
    电脑系统重装后音频驱动程序怎么修复
    java基础
    一文详解Jenkins教程以及Jenkins中的CI/CD自动化部署机制
    智慧电网解决方案-最新全套文件
    ResponseBodyAdvice 返回数据处理
    机器学习 - 决策树:技术全解与案例实战
    ruoyi-cloud 升级mybatis plus 报错 Invalid bound statement (not found)
    设计模式--享元模式(Flyweight Pattern)
    Java:ArrayList源码解析
  • 原文地址:https://blog.csdn.net/w8y56f/article/details/127592685