【问题标题】:Sorting in Descending order using Comparator使用比较器按降序排序
【发布时间】:2017-04-29 17:28:55
【问题描述】:

我正在尝试使用比较器接口按降序对列表进行排序。但是这些值不是按降序排序的。不知道我在这里做错了什么。

public class Student {

    int rollNo;
    String name;
    int age;
    
    public Student(int RollNo, String Name, int Age){
        this.rollNo = RollNo;
        this.name = Name;
        this.age = Age;
    }
}

public class AgeComparator implements Comparator<Student>{

    @Override
    public int compare(Student o1, Student o2) {
        return o1.age > o2.age ? 1 :(o1.age < o2.age ? -1 : 0); //Ascending
         
        //return o1.age < o2.age ? -1 :(o1.age > o2.age ? 1 : 0); // Descending
    }

}

public class Comparator_Sort {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        
        ArrayList<Student> al = new ArrayList<Student>();
        al.add(new Student(5978, "Vishnu", 50));
        al.add(new Student(5979, "Vasanth", 30));
        al.add(new Student(5980, "Santhosh", 40));
        al.add(new Student(5981, "Santhosh", 20));
        al.add(new Student(5982, "Santhosh", 10));
        al.add(new Student(5983, "Santhosh", 5));
        
        
        Collections.sort(al, new AgeComparator());
        
        for(Student s : al){
            System.out.println(s.rollNo+" "+s.name+" "+s.age);
        }
    }
}

我可以按升序对列表进行排序,而我无法按降序对列表进行排序

return o1.age > o2.age ? 1 :(o1.age < o2.age ? -1 : 0); //Sorted in Ascending
return o1.age < o2.age ? -1 :(o1.age > o2.age ? 1 : 0); // Not sorted in Descending

比较器文档 -- 返回:负整数、零或正整数,因为第一个参数小于、等于或大于第二个参数。来源从here找到

谁能告诉我为什么降序排序不起作用?

【问题讨论】:

    标签: java sorting


    【解决方案1】:

    您的两个三元条件运算符产生相同的结果(因为您将&gt;&lt;-11 交换):

    return o1.age > o2.age ? 1 :(o1.age < o2.age ? -1 : 0); //Sorted in Ascending
    return o1.age < o2.age ? -1 :(o1.age > o2.age ? 1 : 0); // Not sorted in Descending
    

    你需要降序:

    return o1.age > o2.age ? -1 :(o1.age < o2.age ? 1 : 0);
    

    【讨论】:

    • 如果你检查我提供的来源,它遵循以下标准
    • 我采用相同的方法,但降序排序不起作用
    • @Aishu -1 : o1 &lt; o2 0 : o1 == o2 +1 : o1 &gt; o2 产生升序。如果要降序排列,则需要将o1o2的角色颠倒过来。
    • 从源代码stackoverflow.com/questions/6478515/…得到一点困惑
    • @Aishu 正如我所说,那个问题(或者更确切地说是公认的答案)描述了获取升序的逻辑。如果 o1 应该在 o2 之前,compare 应该返回一个负值。对于升序,这也意味着 o1o2,则返回负值。
    【解决方案2】:

    你应该写成:

    return o1.age < o2.age ? 1 :(o1.age > o2.age ? -1 : 0); 
    

    或者写成:

    return o1.age > o2.age ? -1 :(o1.age < o2.age ? 1 : 0); 
    

    您当前的尝试仍将按升序对其进行排序。

    【讨论】:

      【解决方案3】:

      @Eran 已经指出了比较器中的错误。

      我想补充一点,您可以直接返回o1.age - o2.age。比较结果不必完全是-11 对于&lt;&gt;,它可能只是负数或正数。

      你也可以打电话给Comparator.reversed。或Comparator.comparing(Student::getAge).reversed()

      【讨论】:

        【解决方案4】:
        return o1.age > o2.age ? -1 :(o1.age < o2.age ? 1 : 0);
        

        虽然对于降序,只需将升序返回语句乘以 -1。像这样

        -1*(return o1.age > o2.age ? 1 :(o1.age < o2.age ? -1 : 0))
        

        【讨论】:

          【解决方案5】:

          由于不可读,滥用三元条件容易出错。

          为什么不简单地为降序比较器写经典的if-else-if

          public class AgeComparatorDesc implements Comparator<Student> {
          
            @Override
            public int compare(Student o1, Student o2) {
              if (o1.age > o2.age) {
                  return -1;
              } else if (o1.age < o2.age) {
                  return 1;
              }    
               return 0;
            }
          
          }
          

          【讨论】:

            【解决方案6】:

            您可以直接使用比较器类实例。下面是代码示例。

            假设您为学生定义了一个 getter 方法 "getAge()"

            Comparator<Student> m_studentComparator = new Comparator<Sudent>() {
                    @Override
                    public int compare(Student lhs, Student rhs) {
                        return rhs.getAge().compareTo(lhs.getAge());  // Descending order
                    }
                };
            
            Collections.sort(<<Your list>> , m_studentComparator);   // this would return the descending order list.
            

            如果你想要一个升序列表,只需将重写方法中的return语句更改为

            return lhs.getAge().compareTo(rjs.getAge());    // Ascending order.
            

            希望这能回答你的问题。

            【讨论】:

            • age 必须是 Integer 类,不能定义为原始类型 int
            • @Davide One 可以做到这一点。这有助于处理年龄为空的情况。谢谢!
            • 当然,我只是想强调这一点
            【解决方案7】:

            年龄值是一个整数,而且好像一直是正数,可以用这个缩短码。

            return o1.age - o2.age; // Ascending
            return o2.age - o1.age; // Descending
            

            此代码不能用于负值。

            例如,

            如果o1.age = 10o2.age = 11,此代码将返回-1 升序和1 降序,这是正确的。

            但是o1.age = -10,o2.age = -11的情况,这个代码会返回1升序和-1降序,这是不正确的。

            【讨论】:

              猜你喜欢
              • 2014-07-24
              • 2013-05-09
              • 2020-02-19
              • 2020-10-08
              • 2017-03-21
              • 1970-01-01
              • 1970-01-01
              • 2013-08-21
              相关资源
              最近更新 更多