最近在学习集合排序问题,对于Comparable接口的compareTo()方法,什么样的表达式表示的是升序、降序呢?

    我们用一道题来进行说明。
分别用Comparable和Comparator两个接口对下列四位同学的成绩做降序排序,如果成绩一样,那在成绩排序的基础上按照年龄由小到大排序。分别用Comparable和Comparator两个接口对下列四位同学的成绩做降序排序,如果成绩一样,那在成绩排序的基础上按照年龄由小到大排序。

 

那么Comparable和Comparator两个接口有什么区别呢?

**Comparable**:强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序,类的compareTo方法被称为它的自然比较方法。只能在类中实现compareTo()一次,不能经常修改类的代码实现自己想要的排序。实现此接口的对象列表(和数组)可以通过Collections.sort(和Arrays.sort)进

行自动排序,对象可以用作有序映射中的键或有序集合中的元素,无需指定比较器。

**Comparator**强行对某个对象进行整体排序。可以将Comparator 传递给sort方法(如Collections.sort或 Arrays.sort),从而允许在排序顺序上实现精确控制。还可以使用Comparator来控制某些数据结构(如有序set或有序映射)的顺序,或者为那些没有自然顺序的对象collection提供排序。

一、如果我们用Comparable接口实现排序,而排序的内容要自定义时则需要重写compareTo()方法,举例:

public class compare {
    public static void main(String[] args) {
        List<Student> list = new ArrayList<Student>();
        list.add(new Student("贾宝玉",14,88.5));
        list.add(new Student("林黛玉",13,90.5));
        list.add(new Student("史湘云",13,85));
        list.add(new Student("薛宝钗",15,91));
        System.out.println("以前的顺序: ");
        for (Student s:list) {
            System.out.println(s);
        }
        System.out.println("现在的顺序: ");
        Collections.sort(list);
        for (Student s:list) {
            System.out.println(s);
        }
    }
}

输出结果:

以前的顺序: 
Student{name='贾宝玉', score=88.5, age=14}
Student{name='林黛玉', score=90.6, age=13}
Student{name='史湘云', score=85.0, age=13}
Student{name='薛宝钗', score=91.0, age=15}
Student{name='凤姐', score=88.5, age=15}
用comparator重写后的顺序: 
Student{name='薛宝钗', score=91.0, age=15}
Student{name='林黛玉', score=90.6, age=13}
Student{name='贾宝玉', score=88.5, age=14}
Student{name='凤姐', score=88.5, age=15}
Student{name='史湘云', score=85.0, age=13}

在这里我这样重写了compareTo()方法:

@Override
public int compareTo(Student o) {
    if (o.getScore() == this.getScore()){
        //按年龄升序
        return (this.getAge() < o.getAge()) ? -1 : (this.getAge() == o.getAge()) ? 0 : 1;
    }else {
        //按成绩降序
        return (this.getScore() < o.getScore()) ? 1 : (this.getScore() == o.getScore()) ? 0 : -1;
    }
}

```

这样写是模仿了Integer里的compareTo方法的源码

public static int compare(int x, int y) {
    return (x < y) ? -1 : ((x == y) ? 0 : 1);
}

首先明白,若compareTo方法 return 0;则集合顺序不变;

若 return 1;集合顺序正序输出;

若 return -1;集合顺序倒序输出;

(x<y)?-1 : (x==y)? 0: 1;
x是自己,y是另一个值。 
若x<y,则rturn -1;

(x<y)? 1 : (x==y)? 0: -1;
x是自己,y是另一个值。 
若x<y,则rturn 1;

这样写的话,年龄从小到大升序排列,成绩就按降序排列。

二、用比较器实现

Collections.sort(list, new Comparator<Student>() {
    //comparator比较器,可以根据需要定制特定的比较规则
    @Override
    public int compare(Student o1, Student o2) {
        if (o1.getScore() == o2.getScore()){
            //按年龄升序
            return (o2.getAge() < o1.getAge()) ?  1 : (o2.getAge() == o1.getAge()) ? 0 : -1;
        }else {
            //按成绩降序
            return (o2.getScore() < o1.getScore()) ? -1 : (o2.getScore() == o1.getScore()) ? 0 : 1;
        }
    }
});
for (Student s:list) {
    System.out.println(s);
}

核心原理相同。

希望对你有帮助~