|
|
|
相同点:都是用于对象比较、排序 |
||
|
Interface in java.lang (提供基础类) |
Interface in java.util (提供工具类) |
|
This interface imposes a total ordering on the objects of each class that implements it. 自然排序:T类自身控制比较方式 一个类实现Comparable接口即表示自身支持排序,Comparable相当于内部比较器:实现Comparable接口的类通过重写接口的compareTo方法,从自身内部控制对象的排序方式 |
A comparison function, which imposes a total ordering on some collection of objects. 定制排序:T类外创建比较器,比较器控制T类对象比较方式 一个类实现Comparator接口后,就成了比较器类,它的对象就相当于外部比较器,T就是这个比较器要控制排序方式的类类型,在比较器类中以T类的对象为compare方法的参数重写compare方法,从T类外部控制T类对象的排序方式 |
方法 |
int compareTo(T o) T类重写此方法指定排序方式 |
int compare(T o1, T o2) 比较器类重写此方法指定T对象排序方式 |
|
适用于自定义类 (很多常见类都实现了Comparable接口:String,Integer,Enum,File...) |
适用于自定义类 或无法通过Comparable接口改变排序方式的常见类 或者用于要将比较器用于多类的情况(比如用多态) |
|
1、以T类的对象为元素的List可以调用Collections.sort()或Arrays.sort()对List排序 2、T类的对象可用作有序映射(如TreeMap)中的键Key,或有序集合(如TreeSet)中的元素,不需要指定比较器 |
1、以T类的对象为元素的List可以调用Collections.sort()或Arrays.sort()对List排序,并通过传入比较器指定T对象的排序方式 2、T类的对象可用作有序映射(如TreeMap)中的键Key,或有序集合(如TreeSet)中的元素,并通过传入比较器指定T对象的排序方式 |
例程 |
public class Tmp implements Comparable<Tmp>{ public int compareTo(Tmp e){ // compare this.e and e } } ArrayList<Tmp> elist=new ArrayList<Tmp>(); {elist.add….} Collections.sort(elist); TreeSet<Tmp> eset=new TreeSet<Tmp>(); {eset.add…}
|
public class CmpTmp implements Comparator<Tmp>{ public int compare(Tmp e1, Tmp e2){ // compare e1 and e2 } } ArrayList<Tmp> elist=new ArrayList<Tmp> (); {elist.add….} CmpTmp cmp=new CmpTmp(); Collections.sort(elist, cmp); cmp.compare(e1,e2); TreeSet<Tmp> eset=new TreeSet<Tmp>(cmp); {eset.add…} |
练习:
import java.util.ArrayList;
import java.util.Collections;
import java.util.TreeSet;
public class CompareTest {
public static void main(String args[]) {
ArrayList<Person> plist = new ArrayList<>();
plist.add(new Person("A", 30));
plist.add(new Person("B", 20));
plist.add(new Person("C", 10));
System.out.println("Original:" + plist);
Collections.sort(plist); // Person按姓名排序实现的Comparable
System.out.println("NameOrder:" + plist);
//PersonComparator是按年龄排序的比较器类
PersonComparator cmp = new PersonComparator();
System.out.println(plist.get(0).getName() + " age compare with " + plist.get(1).getName() + " age = " + cmp.compare(plist.get(0), plist.get(1)));
Collections.sort(plist, cmp); //指定按照年龄排序
System.out.println("AgeOrder:" + plist);
//两种方式建立Person的有序集合
TreeSet<Person> pset1=new TreeSet<Person>();
pset1.add(new Person("Ada",22));
pset1.add(new Person("Bob",11));
System.out.println("Comparable: "+pset1);
TreeSet<Person> pset2=new TreeSet<Person>(cmp);
pset2.add(new Person("ada",22));
pset2.add(new Person("Bob",11));
System.out.println("Comparator:"+pset2);
}
}
// 被比较的类:Person
import java.lang.Comparable;
public class Person implements Comparable<Person> {
private String name;
private int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
@Override
public int compareTo(Person other) { //Person按姓名排序重写Comparable的compareTo()
return name.compareTo(other.getName());
}
@Override
public String toString(){ //如果不重写自定义类的toString,输出的就是hashCode
return name+"("+age+")";
}
}
// 比较器类:PersonComparator
import java.util.Comparator;
public class PersonComparator implements Comparator<Person> {
@Override
public int compare(Person p1, Person p2) { //比较器按年龄排序
return p1.getAge() - p2.getAge();
}
}
输出: