Comparable和Comparator比较

 

在“集合框架”中有两种比较接口:Comparable接口和Comparator接口。像StringIntegerJava内建类实现Comparable接口以提供一定排序方式,但这样只能实现该接口一次。对于那些没有实现Comparable接口的类、或者自定义的类,您可以通过Comparator接口来定义您自己的比较方式。

Comparable接口

 在java.lang包中,Comparable接口适用于一个类有自然顺序的时候。假定对象集合是同一类型,该接口允许您把集合排序成自然顺序。

intcompareTo(Object o): 比较当前实例对象与对象o,如果位于对象o之前,返回负值,如果两个对象在排序中位置相同,则返回0,如果位于对象o后面,则返回正值

 

Comparator接口

 若一个类不能用于实现java.lang.Comparable,或者您不喜欢缺省的Comparable行为并想提供自己的排序顺序(可能多种排序方式),你可以实现Comparator接口,从而定义一个比较器。

 

(1)    intcompare(Object o1, Object o2):

对两个对象o1o2进行比较,如果o1位于o2的前面,则返回负值,如果在排序顺序中认为o1o2是相同的,返回0,如果o1位于o2的后面,则返回正值

 

(2)    booleanequals(Object obj):

指示对象obj是否和比较器相等

 

“与Comparable相似,0返回值不表示元素相等。一个0返回值只是表示两个对象排在同一位置。由Comparator用户决定如何处理。如果两个不相等的元素比较的结果为零,您首先应该确信那就是您要的结果,然后记录行为。”

 

1、自然排序——Comparable

 

JDK类库中,有一部分类实现了Comparable接口,IntegerDoubleString等。Comparable接口有一个comparTo(Objecto)方法,它返回整数类型。对于表达式x.compareTo(y)

 

如果返回值为0,则表示xy相等,

如果返回值大于0,则表示x大于y,

如果返回值小于0,则表示x小于y.

 

TreeSet集合调用对象的compareTo()方法比较集合中的大小,注意不是TreeSet调用它自己的comparTo()方法而是它调用集合中对象的comparTo()方法. TreeSet类本身并没有实现Comparable接口,然后进行升序排列,这种方式称为自然排序.

 

import java.util.HashSet;

import java.util.Set;

 

publicclass  Customer implements Comparable<Object> {

       private  String name;

 

       privateintage;

 

       public  Customer(String name, int age) {

              this.age = age;

              this.name = name;

       }

 

       publicint getAge() {

              returnage;

       }

 

       publicvoid setAge(int age) {

              this.age = age;

       }

 

       public  String getName() {

              returnname;

       }

 

       publicvoid setName(String name) {

              this.name = name;

       }

 

       @Override

       publicboolean equals(Object obj) { // 重写equals方法

              if (this == obj)

                     returntrue;

              if (!(obj instanceof Customer))

                     returnfalse;

              final  Customer other = (Customer) obj;

 

              if (this.name.equals(other.getName()) && this.age == other.getAge())

                     returntrue;

              else

                     returnfalse;

       }

 

       publicstaticvoid main(String[] args) {

              Set<Customer> set = new HashSet<Customer>();

              Customer customer1 = new Customer("Tom", 15);

              Customer customer2 = new Customer("Tom", 15);

              set.add(customer1);

              set.add(customer2);

              System.out.println(set.size());

       }

 

       publicint compareTo(Object o) {

              Customer other = (Customer) o;

 

              // 先按照name属性排序

              if (this.name.compareTo(other.getName()) > 0)

                     return 1;

              if (this.name.compareTo(other.getName()) < 0)

                     return -1;

 

              // 在按照age属性排序

              if (this.age > other.getAge())

                     return 1;

              if (this.age < other.getAge())

                     return -1;

              return  0;

       }

 

       @Override

       publicint hashCode() { // 重写equals方法必须重写hashCode方法

              int result;

              result = (name == null ? 0 : name.hashCode());

              result = 29 * result + age;

              return  result;

       }

}

 

2、客户化排序——Comparable

 

除了自然排序,TreeSet还支持客户化排序java.util.Comparator<Type>接口提供具体的排序方式,<Type>指定被比较的对象的类型,

Comparator有个compar(Type x,Type y)方法,用于比较两个对象的大小,compare(x,y)

大于0时表示x大于y,

小于0表示x小于y

等于0表示x等于y

 

举个例子如果希望TreeSet按照Customer对象的name属性进行降序排列,可以先创建一个实现Comparator接口的类

 

import java.util.Comparator;

import java.util.Iterator;

import java.util.Set;

import java.util.TreeSet;

 

publicclass  CustomerComparator implements Comparator<Customer>{

 

       publicint compare(Customer c1, Customer c2) {

              if(c1.getName().compareTo(c2.getName())>0)return -1;

              if(c1.getName().compareTo(c2.getName())<0)return 1;

             

              return  0;

       }

      

       publicstaticvoid main(String args[]){

              Set<Customer> set = new TreeSet<Customer>(new  CustomerComparator());

             

              Customer customer1= new Customer("Tom",15);

              Customer customer3= new Customer("Jack",16);

              Customer customer2= new Customer("Mike",26);

              set.add(customer1);

              set.add(customer2);

              set.add(customer3);

             

              Iterator<Customer> it =  set.iterator();

              while(it.hasNext()){

                     Customer customer =  it.next();

                     System.out.println(customer.getName()+" "+customer.getAge());

              }

       }

}

 

3Comparable接口和Comparator接口的区别

 

用自定义类实现Comparable接口,那么这个类就具有排序功能,Comparable和具体你要进行排序的类的实例邦定。

Comparator比较灵活,只需要通过构造方法指定一个比较器就行了实现它的自定义类仅仅定义了一种排序方式或排序规则。不言而喻,这种方式比较灵活。我们的要排序的类可以分别和多个实现Comparator接口的类绑定,从而达到可以按自己的意愿实现按多种方式排序的目的。

Comparable——“静态绑定排序”,Comparator——“动态绑定排序”。

 

Comparator接口和具体的实现类,是策略模式的体现,Comparator定义了策略类共同需要实现的接口,而具体策略类实现了具体的比较算法。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值