一、Comparable:
Comparable是java提供的一个排序接口,若一个类实现了Comparable接口,就意味着该类能够实现排序。实现了该接口的对象,可以通过Collections.sort,或者Arrays.sort来进行排序。
1.定义:
Comparable是存在 import java.lang.Comparable中的,打开源码我们可以看到它的定义如下:
public interface Comparable<T> {
public int compareTo(T o);
}
->自定义泛型<T>指的是可以和当前类型进行比较的类型
->接口内只含有一个compareTo(T o)方法,当o小于、等于、或者大于当把对象时返回:正数、0、或负数
2.使用:
(1)假设一个Student类
package IMUHERO;
public class Student
{
private String name;
private int scores;
public Student(String name, int age)
{
super();
this.name = name;
this.scores = age;
}
public String getName()
{ return name; }
public int getScores()
{ return scores; }
}
(2)如何比较两个Student之间的大小呢?
package IMUHERO;
import java.lang.Comparable;
public class Student implements Comparable<Student>
{
private String name;
private int scores;
public Student(String name, int age)
{
super();
this.name = name;
this.scores = age;
}
public String getName()
{ return name; }
public int getScores()
{ return scores; }
@Override
public int compareTo(Student o) {
return this.scores-o.scores;
//此处就定义了一种从小到大排序成绩的方法
//也可以定义从大到小:return this.scores-o.scores;
}
}
->我们只需要implements Comparable<Student>,并且@override compareTo(Student o)就可以。
3.接下去我们使用几个测试用例来看一下效果:
public static void main(String[] args) {
Student[] students=new Student[]{new Student("张小二",95),new Student("李一一",90)};
System.out.println("排序前的先后顺序是:");
for (Student stu:students){
System.out.println("姓名:"+stu.getName()+" 成绩:"+stu.getScores());
}
Arrays.sort(students);
System.out.println("排序后的先后顺序是:");
for (Student stu:students){
System.out.println("姓名:"+stu.getName()+" 成绩:"+stu.getScores());
}
}
->结果
二、Comparator:
Comparator是java提供的一个比较接口,当我们需要对一个类进行排序,而该类本身不支持排序(即没有实现Comparable接口),那么我们可以通过新建一个比较器来进行排序。
新建比较器的过程一般是先新建一个类,实现Comparator接口,并重写compare(T o1,T o2)方法。
1.定义:
Comparator是存在 import java.util.Comparator中的,打开源码我们可以看到它的定义如下:
public interface Comparator<T> {
int compare(T o1, T o2);
boolean equals(Object obj);
}
->自定义泛型<T>指的是将要比较的类型
->该接口包含有两个方法,实现该接口必须要重写compare(T O1,T O2)方法,但是不一定要重写equals(Object obj)方法
->compare方法返回负数、0、正数,依次代表o1<o2,o1==o2,o1>o2
2.使用:
(1)上文中的Student仍旧存在
package IMUHERO;
public class Student
{
private String name;
private int scores;
public Student(String name, int age)
{
super();
this.name = name;
this.scores = age;
}
public String getName()
{ return name; }
public int getScores()
{ return scores; }
}
(2)如何比较两个Student之间的大小呢?
class myCompare implements Comparator<Student>{
@Override
public int compare(Student o1, Student o2) {
return o1.getScores()-o2.getScores();
//此处就定义了一种从小到大排序成绩的方法
//也可以定义从大到小:return o1.scores-o2.scores;
}
}
新建一个myCompare比较器
->在比较器中:我们只需要implements Comparator<Student>,并且@override compare(Student o1,Student o2)就可以。
3.接下去我们使用几个测试用例来看一下效果:
(1)如果按照刚刚的代码进行测试,就会报错,显示找不到比较方法
(2)修改一下代码,添加new myCompare
Arrays.sort(students,new myCompare());
public static void main(String[] args) {
Student[] students=new Student[]{new Student("张小二",95),new Student("李一一",90)};
System.out.println("排序前的先后顺序是:");
for (Student stu:students){
System.out.println("姓名:"+stu.getName()+" 成绩:"+stu.getScores());
}
Arrays.sort(students,new myCompare());
System.out.println("排序后的先后顺序是:");
for (Student stu:students){
System.out.println("姓名:"+stu.getName()+" 成绩:"+stu.getScores());
}
}
->即可得到正确的结果
三、二者的区别
1.Comparable接口需要从源码(示例中是Student类)中去修改compareTo方法
2.Comparator可以通过自己新建一个比较器,从外部定义或者修改类的比较方法
3.简言之,Comparable是从内部修改,Comparator是从外部修改
注:
如果源码是自定义的,可以直接实现Comparable,这样很方便,代码简洁;
但是源码如果是系统的,比如我们要改变priorityQueue(优先队列)的先后顺序为从大到小(源码是从小到大),那么从外部去实现一个自定义比较器会是一个更好的选择。