相同点: Comparable 和 Comparator 都是用来实现集合中元素的比较、排序的
不同点:
1 接口定义的方法不同
Comparable接口里面的方法是 public int compareTo(T o); 在java.lang包下
Comparator接口里面的方法是 int compare(T o1,T o2); 在java.util包下
2 Comparable 是在集合内部定义的方法实现的排序,Comparator 是在集合外部实现的排序,所以,如想实现排序,就需要在集合外定义 Comparator 接口的方法或在集合内实现 Comparable 接口的方法。Comparable 是一个对象本身就已经支持自比较所需要实现的接口(如 String、Integer,Float、Double等 自己就可以完成比较大小操作,已经实现了Comparable接口),自定义的类要在加入list容器中后能够排序,可以实现Comparable接口,在用Collections类的sort方法排序时,如果不指定Comparator,那么就以自然顺序排序,这里的自然顺序就是实现Comparable接口设定的排序方式。
而 Comparator 是一个专用的比较器,在集合外部实现的排序,当这个对象不支持自比较或者自比较函数不能满足你的要求时,你可以写一个比较器来完成两个对象之间大小的比较。
用 Comparator 是策略模式(strategy design pattern),就是不改变对象自身,而用一个策略对象(strategy object)来改变它的行为。 比如:你想对整数采用绝对值大小来排序,Integer 是不符合要求的,你不需要去修改 Integer 类(实际上你也不能这么做)去改变它的排序行为,只要使用一个实现了 Comparator 接口的对象来实现控制它的排序就行了。
简单说一个是自已完成比较,一个是外部程序实现比较的差别而已。
或者说Comparable 是在集合内部定义的方法实现的排序,Comparator 是在集合外部实现的排序。
工作中如何使用:
1 一个类既可以实现Comparable接口也可以实现Comparator接口。
如果希望一个类的比较方式有很多种,而且比较方式具有外部扩展性,那么可以实现Comparator接口,如果一个类默认的实现了Comparable接口,而你又希望再定义一个比较规则,那么你不可能去修改原类,因为这样会破坏封闭开放原则,最好的方法是写一个实现了Comparator接口的类。总的来说,Comparator接口比Comparable接口要灵活。
2 如果一个集合类中存放着一些对象,如果希望对这个集合进行排序,可以使用Collections类里面的sort方法,或Arrays.sort();
比如 sort方法有两种重载形式。
sort(Collection c); 这种方法是根据类T里面默认的排序规则来排序的,即类T里面的compareTo方法
sort(Collection c,Comparator com);这种方法是根据类外面传进来的Comparator实现类类排序的。可以自己定义排序规则。
3 实例说明
类名:Student
属性值:int ID(学号);String name(名称);float score(成绩);
要求:根据学号、姓名或成绩升序,降序排序所有Student实例
思考:
一个类既实现Comparable接口也实现Comparator接口,会按照哪个进行排序呢?
参考代码:com.test.collection.order包下的类
// 有些对象本身就已经支持自比较,如 String、Integer,Float、Double等
public class ComparableDefaultImpl {
public static void main(String[] args) {
int[] intArray = { 13, 35, 0, 4, -17, 9, 1, 3 };
// 直接依据int值的大小来排序的
Arrays.sort(intArray);
System.out.println("下面是Arrays.sort排序");
for (int i = 0; i < intArray.length; i++){
System.out.println(intArray[i]);
}
List list = new ArrayList();
list.add(13);
list.add(10);
list.add(-2);
list.add(-29);
list.add(5);
list.add(87);
list.add(12);
list.add(452);
Collections.sort(list);
System.out.println("下面是Collections.sort排序");
for(Integer i : list){
System.out.println(i);
}
}
}
// 类内部实现Comparable接口
public class Student implements Comparable{
private String ID;
private String name;
private int age;
private Double score;
// 定义两个构造方法
public Student(String ID, String name) {
this(ID,name,0,0);
}
public Student(String ID, String name, int age, double score){
this.ID = ID;
this.name = name;
this.age = age;
this.score = score;
}
public String getID(){
return ID;
}
public String getName(){
return name;
}
public int getAge(){
return age;
}
public double getScore(){
return score;
}
public void setID(String newID){
ID = newID;
}
public void setName(String newName){
name = newName;
}
public void setAge(int newAge){
if(newAge < 0)
newAge = 0;
age = newAge;
}
public void setScore(double newScore){
if( (newScore < 0 )||(newScore > 100))
newScore = 0;
score = newScore;
}
// 重写对象字符串表示方法
@Override
public String toString() {
String info = new String();
info = ID + '\t' + name + '\t' + age + '\t' + score + '\n';
return info;
}
@Override
public int compareTo(Student arg0) {
System.out.println("======================");
// 此种写法为升序,若改为arg0.ID.compareTo(this.ID)则为降序
return this.ID.compareTo(arg0.ID);
}
// 按成绩升序
// @Override
// public int compareTo(Student arg0) {
// return this.score.compareTo(arg0.score);
// }
}
public class StudentComparableTest {
public static void main(String[] args) {
// 定义初始化长度
final int STUDENT_NUM = 4;
Student[] allStudents = new Student[STUDENT_NUM];
// 初始化
allStudents[0] = new Student("00001", "a");
allStudents[1] = new Student("00003", "b");
allStudents[2] = new Student("00002", "c");
allStudents[3] = new Student("00004", "d");
// 批量初始化年龄和成绩
for (int i = 0; i < allStudents.length; i++) {
allStudents[i].setAge(i * 10);
}
for (int i = 0; i < allStudents.length; i++) {
allStudents[i].setScore(99 - i * 1.5);
}
// 按学号升序排序
Arrays.sort(allStudents);
// 显示学生信息
System.out.println("学号" + "\t姓名" + "\t年龄" + "\t成绩");
for (int i = 0; i < allStudents.length; i++) {
System.out.print(allStudents[i]);
}
}
}
public class StudentComparatorTest {
public static void main(String[] args) {
// 定义初始化长度
final int STUDENT_NUM = 4;
Student[] allStudents = new Student[STUDENT_NUM];
// 初始化学生数据
allStudents[0] = new Student("00001", "a");
allStudents[1] = new Student("00003", "b");
allStudents[2] = new Student("00002", "c");
allStudents[3] = new Student("00004", "d");
// 批量初始化年龄和成绩
for (int i = 0; i < allStudents.length; i++) {
allStudents[i].setAge(i * 10);
}
for (int i = 0; i < allStudents.length; i++) {
allStudents[i].setScore(99 - i * 1.5);
}
// 按姓名升序排序
Arrays.sort(allStudents, new ComparatorWithNameUP());
// 显示学生信息
System.out.println("按姓名升序排序结果:");
System.out.println("学号" + "\t姓名" + "\t年龄" + "\t成绩");
for (int i = 0; i < allStudents.length; i++) {
System.out.print(allStudents[i]);
}
// 按姓名降序排序
Arrays.sort(allStudents, new ComparatorWithNameDown());
// 显示学生信息
System.out.println("按姓名降序排序结果:");
System.out.println("学号" + "\t姓名" + "\t年龄" + "\t成绩");
for (int i = 0; i < allStudents.length; i++) {
System.out.print(allStudents[i]);
}
// 按成绩降序排序
Arrays.sort(allStudents, new ComparatorWithScoreDown());
// 显示学生信息
System.out.println("按成绩降序排序结果:");
System.out.println("学号" + "\t姓名" + "\t年龄" + "\t成绩");
for (int i = 0; i < allStudents.length; i++) {
System.out.print(allStudents[i]);
}
// 按成绩升序排序
Arrays.sort(allStudents, new ComparatorWithScoreUp());
// 显示学生信息
System.out.println("按成绩升序排序结果:");
System.out.println("学号" + "\t姓名" + "\t年龄" + "\t成绩");
for (int i = 0; i < allStudents.length; i++) {
System.out.print(allStudents[i]);
}
}
}
// 按姓名进行升序排序的外部类,用Comparator接口
class ComparatorWithNameUP implements Comparator {
@Override
public int compare(Student arg0, Student arg1) {
return arg0.getName().compareTo(arg1.getName());
}
}
// 按姓名进行降序排序的外部类,用Comparator接口
class ComparatorWithNameDown implements Comparator {
@Override
public int compare(Student arg0, Student arg1) {
return arg1.getName().compareTo(arg0.getName());
}
}
// 按成绩降序
class ComparatorWithScoreDown implements Comparator {
@Override
public int compare(Student arg0, Student arg1) {
if (arg1.getScore() > arg0.getScore())
return 1;
else {
if (arg1.getScore() == arg0.getScore())
return 0;
else
return -1;
}
}
}
// 按成绩升序
class ComparatorWithScoreUp implements Comparator {
@Override
public int compare(Student arg0, Student arg1) {
if (arg0.getScore() > arg1.getScore())
return 1;
else {
if (arg0.getScore() == arg1.getScore())
return 0;
else
return -1;
}
}
}