Comparable:强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序,类的compareTo方法被称为它的自然比较方法。只能在类中实现compareTo()一次,不能经常修改类的代码实现自己想要的排序。实现此接口的对象列表(和数组)可以通过Collections.sort(和Arrays.sort)进行自动排序,对象可以用作有序映射中的键或有序集合中的元素,无需指定比较器。
Comparator强行对某个对象进行整体排序。可以将Comparator 传递给sort方法(如Collections.sort或 Arrays.sort),从而允许在排序顺序上实现精确控制。还可以使用Comparator来控制某些数据结构(如有序set或有序映射)的顺序,或者为那些没有自然顺序的对象collection提供排序。
Comparable接口
Comparable接口中只有一个方法public int compareTo(T o)
,一个类可以通过实现该接口的方法来定义这个类的对象的整体排序方式。这种方式相当于固定了该类的比较方式,到时候可以通过Collections.sort(和Arrays.sort)
对该类的集合进行自动排序。
public class Test {
public static void main(String[] args) throws ParseException {
ArrayList list = new ArrayList();
list.add(new Person(20,"aaaaa"));
list.add(new Person(19,"aaaaa"));
list.add(new Person(20,"bbbbb"));
list.add(new Person(30,"ddddd"));
list.add(new Person(15,"eeeee"));
System.out.println(list);
Collections.sort(list);
System.out.println(list);
}
}
class Person implements Comparable<Person>{
private int age;
private String name;
...
public int compareTo(Person person) {
//先通过年龄来进行升序排序
int i = this.age - person.age;
if (i == 0){
//如果相等则通过调用String的compareTo方法来进行升序排序
return this.name.compareTo(person.name);
}
return i;
}
}
输出结果:
按年龄升序、姓名升序进行排序
排序前:[{age=20, name='aaaaa'}, {age=19, name='aaaaa'}, {age=20, name='bbbbb'}, {age=30, name='ddddd'}, {age=15, name='eeeee'}]
排序后:[{age=15, name='eeeee'}, {age=19, name='aaaaa'}, {age=20, name='aaaaa'}, {age=20, name='bbbbb'}, {age=30, name='ddddd'}]
Comparator接口
如果一个类以及实现了Comparable接口实现了以及定义好的排序方式,但是并不是我们需要的,此时我们可以通过实现Comparator接口来自定义排序方式。该接口中的主要抽象方法为int compare(T o1, T o2)
。
public class Test {
public static void main(String[] args) throws ParseException {
ArrayList list = new ArrayList();
list.add(new Person(20,"aaaaa"));
list.add(new Person(19,"aaaaa"));
list.add(new Person(20,"bbbbb"));
list.add(new Person(30,"ddddd"));
list.add(new Person(15,"eeeee"));
System.out.println(list);
Collections.sort(list, new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
//通过年龄进行升序排序
int i = o1.getAge() - o2.getAge();
if (i == 0)
//如果年龄相等,则通过调用String的compareTo方法进行降序排序
return o2.getName().compareTo(o1.getName());
return i;
}
});
System.out.println(list);
}
}
class Person{
private int age;
private String name;
...
}
输出结果:
按年龄升序、姓名降序进行排序
排序前:[{age=20, name='aaaaa'}, {age=19, name='aaaaa'}, {age=20, name='bbbbb'}, {age=30, name='ddddd'}, {age=15, name='eeeee'}]
排序后:[{age=15, name='eeeee'}, {age=19, name='aaaaa'}, {age=20, name='bbbbb'}, {age=20, name='aaaaa'}, {age=30, name='ddddd'}]
注意:关于排序的升序与降序问题,如果返回值为负数,则第一个参数放在前面,也就是进行升序排序。如果返回值为负数,则第一个参数放在后面,也就是进行降序排序
当一个类没有提供比较器或者提供的比较器(Comparable)不适用时,就可以使用外部比较器(Comparator)