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

Posted 石头wang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了怎么看出 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,即 按字典顺序比较两个字符串

以上是关于怎么看出 Java 的 Comparator是升序还是降序的主要内容,如果未能解决你的问题,请参考以下文章

关于java使用Comparator多列数据升序、降序排列的问题。哪位大侠能解决

请教:JAVA中,comparator接口如何对double型数据进行排序。

Java 里的Comparator接口里的compare方法怎么确定升降序的?

java中,如何实现集合的升序和降序排列

java Comparator.compare(T o1,To2) 返回负整数、正整数的意义

JAVA中Comparator的使用