Java中Comparable和Comparator比较

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

Comparable接口

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

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

 

Comparator接口

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

 

(1)    int compare(Object o1, Object o2): 

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

 

(2)    boolean equals(Object obj): 

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

 

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

 

1、自然排序——Comparable

 

JDK类库中,有一部分类实现了Comparable接口,Integer DoubleString等。 Comparable接口有一个comparTo(Object o)方法,它返回整数类型。对于表达式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;

 

public class Customer implements Comparable {

private String name;

 

private int age;

 

public Customer(String name, int age) {

this.age = age;

this.name = name;

}

 

public int getAge() {

return age;

}

 

public void setAge(int age) {

this.age = age;

}

 

public String getName() {

return name;

}

 

public void setName(String name) {

this.name = name;

}

 

@Override

public boolean equals(Object obj) { // 重写equals方法

if (this == obj)

return true;

if (!(obj instanceof Customer))

return false;

final Customer other = (Customer) obj;

 

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

return true;

else

return false;

}

 

public static void main(String[] args) {

Set set = new HashSet();

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

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

set.add(customer1);

set.add(customer2);

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

}

 

public int 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

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

int result;

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

result = 29 * result + age;

return result;

}

}

 

2客户化排序——Comparable

 

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

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

大于0时表示x大于y,

小于0表示x小于

等于0表示x等于

 

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

 

import java.util.Comparator;

import java.util.Iterator;

import java.util.Set;

import java.util.TreeSet;

 

public class CustomerComparator implements Comparator{

 

public int 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;

}

public static void main(String args[]){

Set set = new TreeSet(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 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定义了策略类共同需要实现的接口,而具体策略类实现了具体的比较算法。

 

你可能感兴趣的:(java,集合,排序)