什么决定了比较器/可比较集合类中的升序或降序?

我知道我们可以根据我们的要求对存储在集合中的对象进行排序或排序。

虽然我得到了深刻的理解,但我不相信这样的事实,即排列的升序和降序是通过(a - b)->递增或(b - a)->降序实现的,其中“a”和“b”是我们选择比较的类成员。

例:

public int compareTo(Student s) {
     return this.grade - s.grade; //ascending order 
    // return s.grade - this.grade; // descending order
}

对对象元素进行排序背后的逻辑是什么?如果正 1 将“this.grade”移到前面并将“s.grade”放在下一个顺序,为什么不换一种方式呢?谁来验证比较结果(+1,-1,0),然后分别按升序或降序排列,是否有任何文档描述此部件的内部工作?

public class Student implements Comparable <Student>{
    String name;
    int grade;
    public Student(String name, int grade) {
        this.name = name;
        this.grade = grade;
    }
    public int compareTo(Student s) {
         return this.grade - s.grade; //ascending order 
        // return s.grade - this.grade; // descending order
    }
    public String toString() {
        return this.name + ", " + this.grade;
    }
}

请分享,非常感谢!


编辑:

我得到了Java文档,我的问题是这样的:

sort these grades (13, 2)

Case ascending -> return this.grade - s.grade;

picture in my mind: 
compare (13, 2) , (13 - 2) > 0 so move 2 to front.
result -> 2, 13
------
Case descending -> return s.grade - this.grade;

picture in my mind: 
compare (2, 13) , (2 - 13) < 0 so move 13 to front.

result -> 13, 2

“这是怎么发生的?”这是我最初的问题。我读了文档,仍然无法弄清楚。


答案 1

对对象元素进行排序背后的逻辑是什么?如果正 1 将“this.grade”移到前面并将“s.grade”放在下一个顺序,为什么不换一种方式呢?

使用负数表示“这小于那个”,正数表示“这比那个多”和0表示“这两件事是相等的”已经在许多计算机语言中存在了30多年。

谁来验证比较结果(+1,-1,0),然后分别按升序/降序排列,是否有任何文档描述此部件的内部工作?

有几个内部类使用返回值对数组或集合中的元素重新排序,包括

Collections.sort() Arrays.sort() TreeSet

编辑

要回答它是如何工作的,你将不得不查看我上面列出的每个类的源代码。其中一些非常复杂,试图使排序尽可能高效。但总的来说,这一切都归结为这样的代码:

if( data[i].compareTo(data[j]) > 0 ){
   // swap data[i] and  data[j]
}

答案 2

@DavidPrun 好问题。我尝试用一个例子来解释这一点。

(x,y) -> (2, 5)

升序 (x.compareTo(y)):

if x.compareTo(y) == 1, then x > y , since y is smaller than x, you would have to move y in front of x.

2.compareTo(5) == 1 , Then don't move 5 in front of 2.

降序 (y.compareTo(x)):

if y.compareTo(x) == 1, then y > x , since y is greater than x, you would have to move y in front of x.

5.compareTo(2) == -1 , Move 5 in front of 2.

基本上,如果 compareTo 方法的结果是 1,我们将始终将 y 移到 x 前面。


推荐