首先Comparable和Comparator和都是接口,Comparable相当是作为一个标记,若一个类实现了Comparable接口,就意味着"该类支持排序",由你需要排序的类来继承。而Comparator是比较器接口,继承该接口实现接口与当中的比较规则,实现一个比较器类。
Comparable的使用
如果我Student类(学生属性有age,name),该类被存放在students集合中。
class Sdudent implements Comparable<Sdudent> {
String name;
int age;
@Override
public String toString() {
return "" + name + ":" + age;
}
public Sdudent(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
如果我想按age排序,用Student类继承Comparable<Student>接口,如果按age排序我必须再Student类中重写以下方法:
//按年龄排序
@Override
public int compareTo(Sdudent o) {
return age-o.age;
}
使用时:
public static void main(String[] args) {
ArrayList<Sdudent> sdudents = new ArrayList<>();
sdudents.add(new Sdudent("liudehua", 22));
sdudents.add(new Sdudent("zhourunfa", 33));
sdudents.add(new Sdudent("xinxinzhou", 44));
Collections.sort(sdudents);
for (Sdudent s : sdudents) {
System.out.println(s);
}
}
输出结果:
liudehua:22
xinxinzhou:44
zhourunfa:33
如果我又突然想用name排序,那我要把compareTo方法修改成如下:
//按名字排序
@Override
public int compareTo(Sdudent o) {
return name.compareTo(o.name);
}
显然我只能让students按age或name来排序;那么如何解决这个矛盾呢
Comparator的使用
我可以实现两个比较器
name比较器:
//一个名字比较器
class NameComparator implements Comparator<Sdudent> {
@Override
public int compare(Sdudent o1, Sdudent o2) {
return o1.name.compareTo(o2.name);
}
}
age比较器:
//一个年龄比较器
class AgeComparator implements Comparator<Sdudent> {
@Override
public int compare(Sdudent o1, Sdudent o2) {
return o1.age - o2.age;
}
}
使用时:
public static void main(String[] args) {
ArrayList<Sdudent> sdudents = new ArrayList<>();
sdudents.add(new Sdudent("liudehua", 22));
sdudents.add(new Sdudent("zhourunfa", 33));
sdudents.add(new Sdudent("xinxinzhou", 44));
System.out.println("装载name比较器的排序结果:");
Collections.sort(sdudents, new NameComparator());
for (Sdudent s : sdudents) {
System.out.println(s);
}
System.out.println("-----------------------");
System.out.println("装载age比较器的排序结果:");
Collections.sort(sdudents, new AgeComparator());
for (Sdudent s : sdudents) {
System.out.println(s);
}
}
输出结果:
装载name比较器的排序结果:
liudehua:22
xinxinzhou:44
zhourunfa:33
-----------------------
装载age比较器的排序结果:
liudehua:22
zhourunfa:33
xinxinzhou:44
我们便能按照需求装载不同的比较器来确定排序规则,较之Comparable更为灵活
总结
Comparable相当于“内部比较器”,而Comparator相当于“外部比较器
Comparator的使用更加灵活,在使用时建议优先使用