- Comparable:强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序,类的compareTo方法被称为它的自然比较方法。只能在类中实现compareTo()一次,不能经常修改类的代码实现自己想要的排序。实现此接口的对象列表(和数组)可以通过Collections.sort(和Arrays.sort)进行自动排序,对象可以用作有序映射中的键或有序集合中的元素,无需指定比较器。
- Comparator强行对某个对象进行整体排序。可以将Comparator 传递给sort方法(如Collections.sort或Arrays.sort),从而允许在排序顺序上实现精确控制。还可以使用Comparator来控制某些数据结构(如有序set或有序映射)的顺序,或者为那些没有自然顺序的对象collection提供排序。
我们的自定义类是无法使用 Collections.sort 进行排序的,要想用 sort 方法进行排序,有两种方式:
- 待排序对象的类实现 Comparable接口(
同时实现该接口的 compareTo 方法
)。 - 新建一个 Comparator 接口的实现类(
同时实现该接口的 compare 方法
),用这个类对待排序序列进行排序。
1. 待排序对象的类实现 Comparable接口。
单个参数,此时T需要实现 Comparable 接口,同时实现该接口的 compareTo 方法:
public class Student implements Comparable<Student> {
public int age;
public int score;
public String name;
public Student(int age, int score, String name) {
this.age = age;
this.score = score;
this.name = name;
}
//对于Student,先比较分数,谁的分数高谁的排序就大;如果分数一样,则比较年龄,年龄大的就大
//返回1说明: 当前对象 > 待比较对象
//返回-1说明:当前对象 > 待比较对象
//返回0说明: 当前对象 = 待比较对象
@Override
public int compareTo(Student o) {
return this.score > o.score ? 1 :
this.score < o.score ? -1 :
this.age > o.age ? 1 :
this.age < o.age ? -1 : 0;
}
@Override
public String toString() {
return "Student{" +
"age=" + age +
", score=" + score +
", name='" + name + '\'' +
'}';
}
}
测试类:
import java.util.ArrayList;
import java.util.Collections;
public class Test {
public static void main(String[] args) {
ArrayList<Student> students = new ArrayList<>();
students.add(new Student(30, 100, "张三"));
students.add(new Student(18, 90, "李四"));
students.add(new Student(20, 90, "王五"));
students.add(new Student(29, 100, "赵六"));
System.out.println(students);
//[Student{age=30, score=100, name='张三'},
// Student{age=18, score=90, name='李四'},
// Student{age=20, score=90, name='王五'},
// Student{age=29, score=100, name='赵六'}]
Collections.sort(students); //升序排列
System.out.println(students);
//[Student{age=18, score=90, name='李四'},
// Student{age=20, score=90, name='王五'},
// Student{age=29, score=100, name='赵六'},
// Student{age=30, score=100, name='张三'}]
}
2. 新建一个 Comparator 接口的实现类(同时实现该接口的 compare 方法
),用这个类对待排序序列进行排序。
sort(List<T> list, Comparator<? super T> c)
单个参数,此时对T 没有特殊限制要求(实不实现Comparable接口都不影响)。
public class Student {
public int age;
public int score;
public String name;
public Student(int age, int score, String name) {
this.age = age;
this.score = score;
this.name = name;
}
@Override
public String toString() {
return "Student{" +
"age=" + age +
", score=" + score +
", name='" + name + '\'' +
'}';
}
}
测试类:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
public class Test {
public static void main(String[] args) {
ArrayList<Student> students = new ArrayList<>();
students.add(new Student(30, 100, "张三"));
students.add(new Student(18, 90, "李四"));
students.add(new Student(20, 90, "王五"));
students.add(new Student(29, 100, "赵六"));
System.out.println(students);
//[Student{age=30, score=100, name='张三'},
// Student{age=18, score=90, name='李四'},
// Student{age=20, score=90, name='王五'},
// Student{age=29, score=100, name='赵六'}]
//创建 comparator
// o1>o2 返回 1 ,则升序排列
// o1<o2 返回-1 ,则降序序排列
Comparator<Student> comparator = new Comparator<>() {
@Override
public int compare(Student o1, Student o2) {
return o1.score < o2.score ? 1 :
o1.score > o2.score ? -1 :
o1.age < o2.age ? 1 :
o1.age > o2.age ? -1 : 0;
}
};
//也可以写成匿名内部类的方式
/*Collections.sort(students, new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return 0;
}
});*/
//排序
Collections.sort(students, comparator);
System.out.println(students);
//[Student{age=30, score=100, name='张三'},
// Student{age=29, score=100, name='赵六'},
// Student{age=20, score=90, name='王五'},
// Student{age=18, score=90, name='李四'}]
}
}
1.compareTo(Object o)方法是java.lang.Comparable接口中的方法,当需要对某个类的对象进行排序时,该类需要实现Comparable接口的,必须重写public int compareTo(T o)方法。
2.compare(Object o1,Object o2)方法是java.util.Comparator接口的方法,它实际上用的是待比较对象的compareTo(Object o)方法。