一,Comparable接口,位于Java.lang包下
其中只有唯一的方法:compareTo()
当对象实现了这个接口,覆盖compareTo方法,实现自己的比较规则,那么对这个对象数组排序就变得简单了:
Arrays.sort(a); //a为实现了这个接口的对象数组
把对象放到TreeSet,TreeMap这些集合时,也可以进行排序。
comparTo()的通用约定:
1,自反性 sgn(x.compareTo(y)) = -sgn(y.compareTo(x))
2,传递性 x.compareTo(y)>0 && y.compareTo(z)>0 ----> x.compareTo(z)>0
3,对称性 x.compareTo(y)==0 ---->x.compareTo(z) ==y.compareTo(z)
4,强烈建议 (x.compareTo(y)==0) == (x.equals(y)) ,这并不是真正的规则,只是说compareTo方法施加的等同性测试,在通常情况下应该返回与equals方法同样的结果。
如果一个类的compareTo方法施加了一个与equals方法不一致的顺序关系,它仍然能正常工作,但是,如果一个有序集合包含了该类元素,这个集合就可能无法遵守相应集合接口的通用约定。因为这些集合是按照equals方法来定义的。
举例:BigDecimal类,实现了Comparable接口,根据BigDecimal API,,值相等但具有不同标度的两个BigDecimal对象(如,2.0和2.00被认为是相等的)
BigDecimal bg1 = new BigDecimal("1.0");BigDecimal bg1 = new BigDecimal("1.00")
在HashSet集合中添加bg1和bg2,这个集合将包含两个元素,因为是通过equals方法比较的,但是,如果将两个对象放到TreeSet 中时,集合只有一个元素,因为TreeSet通过compareTo方法判断集合中是否已经有对象,但1.0和1.00被认为是相等的,所以通过compareTo方法比较是相等的。所以BigDecimal类的compareTo方法和equals方法不一致。用法:
class MyComparable implements Comparable{
private int id;
public int compareTo(MyComparable m){
if(id>m.id){
return 1;
}
return 0;
}
二,Comparator接口, 位于java.util包下
实现Comparable接口的类是将比较代码嵌入自身类中,而Comparator是在一个独立的类中比较,集合需要排序时使用这个比较器。
举例:第一种实现Comparable接口,
class Book implements Comparable{
private int id;
public int compareTo(Book book){
if(id>book.id){
return 1;
}return 0;
}
把之前的Book存入TreeSet中,TreeSet ,会自动排序。
第二种利用实现了Comparator的比较器类
class Book{
private int id;
Book(int id){
this.id = id;
}
public int getId(){
return id;
}
public void setId(int id){
this.id = id;
}
}
class MyComparator implements Comparator{
public int compare(Book b1,Book b2){
return b1.getId()-b2.getId(); //因为book.id大于0,所以不用考虑溢出的情况}}使用比较器
}
MyComparator mycomparator = new MyComparator();
TreeSet tset = new TreeSet( mycomparator );