简体   繁体   English

什么决定了 Comparator / Comparable 集合类中的升序或降序?

[英]What determines ascending or descending order in Comparator / Comparable collection class?

I understand we can sort or order the objects, stored in Collection as per our requirement(s).我知道我们可以根据我们的要求对存储在 Collection 中的对象进行排序或排序。

While I get deep understanding, I am not convinced by the fact that ascending and descending order of arrangement is achieved by (a - b) ->ascending or (b - a) -> descending where "a" and "b" are class members we chose to compare.虽然我得到了深刻的理解,但我不相信这样的事实,即升序和降序排列是通过 (a - b) -> 升序或 (b - a) -> 降序实现的,其中 "a" 和 "b" 是类我们选择比较的成员。

Example:例子:

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

What is logic behind ordering object elements?排序对象元素背后的逻辑是什么? how "(this.grade - s.grade)" if positive 1 moves "this.grade" front and puts "s.grade" next in order, why not other way around? "(this.grade - s.grade)" 如果正 1 将 "this.grade" 移到前面并按顺序放置 "s.grade",为什么不反过来呢? Who validates the compare result (+1, -1, 0) and then puts in ascending order or descending order respectively, is there any documentation that describes internal working of this part?谁验证比较结果(+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;
    }
}

Please share, thank you much!请分享,非常感谢!


Edit:编辑:

I get the Java docs, my question is this:我得到了 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

"How does this happen?" “这是怎么回事?” was my original question.是我原来的问题。 I read the docs, still couldn't figure out.我阅读了文档,仍然无法弄清楚。

What is logic behind ordering object elements?排序对象元素背后的逻辑是什么? how "(this.grade - s.grade)" if positive 1 moves "this.grade" front and puts "s.grade" next in order, why not other way around? "(this.grade - s.grade)" 如果正 1 将 "this.grade" 移到前面并按顺序放置 "s.grade",为什么不反过来呢?

Using negative numbers to say "this is less than that", positive numbers to say "this is more than that" and 0 to say "these 2 things are equal" has been in many computer languages for 30+ years.用负数表示“这小于那个”,用正数表示“这大于那个”,用 0 表示“这两件事相等”已经在许多计算机语言中使用了 30 多年。

Who validates the compare result (+1, -1, 0) and then puts in ascending order / descending order respectively, is there any documentation that describes internal working of this part?谁验证比较结果(+1、-1、0),然后分别按升序/降序排列,是否有描述这部分内部工作的文档?

There are several internal classes that use the return value to reorder elements in arrays or collections including有几个内部类使用返回值对数组或集合中的元素进行重新排序,包括

Collections.sort() Arrays.sort() TreeSet Collections.sort() Arrays.sort() TreeSet

EDIT编辑

To answer HOW that works you will have to look at the source code for each of the classes I listed above.要回答它是如何工作的,您必须查看我上面列出的每个类的源代码。 Some of them are quite complicated to try to make the sorting as efficient as possible.其中一些非常复杂,试图使排序尽可能高效。 But in general, it all boils down to code like this:但总的来说,这一切都归结为这样的代码:

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

@DavidPrun Good question. @DavidPrun 好问题。 I have tried explaining this with an example.我试过用一个例子来解释这一点。

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

Ascending Order (x.compareTo(y)):升序(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.

Descending Order (y.compareTo(x)):降序(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.

Basically, we will always move y in front of x, if the result of compareTo method is 1.基本上,如果 compareTo 方法的结果为 1,我们将始终将 y 移动到 x 之前。

The Collections.sort() methods does . Collections.sort()方法确实如此。

Somewhere in the sort function in java, the fucntion compareTo(Comparable other) is called to determine how your comparable should be compared to the other comparable.在 java 的sort函数中,函数compareTo(Comparable other)被调用以确定您的可比较对象与其他可比较对象的比较方式。

Lets say I have circle that I want to compare by diameter假设我有一个圆,我想按直径进行比较

public class Circle implements Comparable<Cricle> {
 int diameter;
 //constructor
 public int compareTo(Circle c){
  return this.diameter-c.diameter;
   }

now lets make an array of circles :现在让我们制作一个圆圈数组:

ArrayList<Circle> collection = new ArrayList;
collection.add(new Circle(10)); // and more circles

Now lets assume this is the sorting algorithm defined in Collection.sort() :现在让我们假设这是在 Collection.sort() 中定义的排序算法:

  Comparable tmp;
  for(int i=0;i<collection.size();i++){
   for(int j=i;j<collection.size();j++){
    if(collection.get(j).compareTo(collection.get(i)>0){
      //swap
      tmp=collection.get(i);
      collection.set(i,collection.get(j));
      collection.set(j,tmp);
     }
    }
   }
  

Java doesn't use bubble sort of course, but this is a rough example of how your implementation of compareTo will decide the oreder. Java 当然不使用冒泡排序,但这是一个粗略的例子,说明您的compareTo实现将如何决定排序。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM