相同点:两者都是接口;都是用于比较,用于排序。Collections.sort(List<T> list)方法中,泛型T必须实现Comparable;如果泛型T没有实现Comparable,必须构造的时候:Collections.sort(List<T> list,Comparator<T> comparator)。排序用的数据结构比如PriorityQueue<T>(),TreeSet<T>(),中的“T”和TreeMap<K,V>中的K的情况和上述的“T”是一样的。
不同点:
从上面函数的结构可以看出:实现Comparable的类可以直接当做泛型,直接用于比较,因为实现Comparable的类会实现
public int compareTo(Object o)。该方法返回正数表示调用方法者大于对象o。排序方法或者有序的数据结构就根据这个方法将对象们排序(默认从小到大);
实现Comparator的类是比较器类,比较器类实现了Comparator的 public int compare(T o1,To2);用于比较o1和o2.排序方法或者有序的数据结构用比较器进行排序。
比较器其实应用了策略模式,比较器对象就是一个策略,传入到需要排序的算法中。
上代码示例:
public class MyComparable implements Comparable {
int val;
public MyComparable(int val){
this.val = val;
}
@Override
public int compareTo(Object o) {
if (o instanceof MyComparable){
MyComparable myComparable = (MyComparable) o;
return this.val - myComparable.val;
}
else return 0;
}
}
public abstract class MyAbstractClass {
private int x;
public MyAbstractClass(int x){
this.x = x;
}
public abstract void execute();
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
}
由于MyAbstractClass没有实现Comparable,所以用于比较得写个Comparator:
public class MyComparator implements Comparator{
@Override
public int compare(Object o1, Object o2) {
if (o1 instanceof MyAbstractClass && o2 instanceof MyAbstractClass){
MyAbstractClass object1 = (MyAbstractClass) o1;
MyAbstractClass object2 = (MyAbstractClass) o2;
return object1.getX() - object2.getX();
}
return 0;
}
}
测试:
public void sort(){ List<MyAbstractClass> list = new ArrayList<>(); PriorityQueue<MyAbstractClass> priorityQueue = new PriorityQueue<>();//观察没有实现Comparable的类放在PriorityQueue会怎样 for (int i = 10;i > 0;i--){ MyAbstractClass myAbstractClass = new MyAbstractClass(i) { @Override public void execute() { } }; list.add(myAbstractClass); //priorityQueue<MyAbstractClass>().add(myAbstractClass);//会报错,因为TreeSet的泛型必须实现Comparable,或者在TreeSet对象构造时候加上Comparator } for (MyAbstractClass myAbstractClass:list) System.out.println(myAbstractClass.getX());//输出排序前的 Collections.sort(list,new MyComparator());//排序 for (MyAbstractClass myAbstractClass:list) System.out.println(myAbstractClass.getX()); System.out.println("现在开始是PriorityQueue的排序情况"); for (MyAbstractClass myAbstractClass:priorityQueue){ System.out.println(myAbstractClass.getX()); } List<MyComparable> myComparables = new ArrayList<>(); Collections.sort(myComparables); }