Comparable和Comparator的比较

来源:互联网 发布:新浪域名国外的 编辑:程序博客网 时间:2024/06/05 16:32

一,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 );

原创粉丝点击