java的比较器有两类,分别是Comparable接口和Comparator接口。
在为对象数组或者对象对象集合进行排序时,比较器的作用非常明显,首先来讲解Comparable接口。对象本身只要实现Comparable接口,那么该类的实例就是可以排序的(实现其comparTo()方法).只要实现了Comparable接口,就可以调用Collections的sort方法对集合中的元素排序.
实例如下:
public classPerson implements Comparable{
privateString name;
privateint age;
publicString getName() {
returnname;
}
publicvoid setName(String name) {
this.name= name;
}
publicint getAge() {
returnage;
}
publicvoid setAge(int age) {
this.age= age;
}
publicint compareTo(Person o) {
if(this.ageo.age){
return1;
}
return0;
}
@Override
publicString toString() {
returnthis.name+":"+this.age;
}
@Override
publicint hashCode() {
finalint prime = 31;
intresult = 1;
result= prime * result + age;
result= prime * result + ((name == null) ? 0 : name.hashCode());
returnresult;
}
@Override
publicboolean equals(Object obj) {
if(this == obj)
returntrue;
if(obj == null)
returnfalse;
if(getClass() != obj.getClass())
returnfalse;
Personother = (Person) obj;
if(age != other.age)
returnfalse;
if(name == null) {
if(other.name != null)
returnfalse;
}else if (!name.equals(other.name))
returnfalse;
returntrue;
}
publicPerson(String name, int age) {
super();
this.name= name;
this.age= age;
}
}
测试代码:
public classTestSort {
public static void main(String[] args) {
Personp1=new Person("冬冬", 22);
Personp2=new Person("小王", 14);
Personp3=new Person("老赵", 42);
Personp4=new Person("老李", 41);
Listlist=new ArrayList();
Collections.addAll(list,p1,p2,p3,p4);
System.out.println("使用Comparable比较器");
System.out.println(list);
Collections.sort(list);
System.out.println(list);
}
}
程序运行结果:
使用Comparable比较器
[冬冬:22, 小王:14, 老赵:42, 老李:41]
[小王:14, 冬冬:22, 老李:41, 老赵:42]
但是在设计类的时候,往往没有考虑到让类实现Comparable接口或者只是偶尔需要用到对类对象排序,那么我们就需要用到另外的一个比较器接口Comparator。
public interface Comparator {
int compare(Object o1, Object o2);
boolean equals(Object obj);
}
注意到实现Comparator的接口需要重写compare和equals两个方法,但是一般来说我们只需要实现compare方法。这是因为有自定义类默继承Object类,而Object中已经将equals()实现,另外为了设计一个良好的类,我们在刚开始设计类的时候一般就重写了hashcode和equals这两个方法。
代码实例:
public classPerson2 {
privateString name;
privateint age;
publicString getName() {
returnname;
}
publicvoid setName(String name) {
this.name= name;
}
publicint getAge() {
returnage;
}
publicvoid setAge(int age) {
this.age= age;
}
@Override
publicString toString() {
returnthis.name+":"+this.age;
}
@Override
publicint hashCode() {
finalint prime = 31;
intresult = 1;
result= prime * result + age;
result= prime * result + ((name == null) ? 0 : name.hashCode());
returnresult;
}
@Override
publicboolean equals(Object obj) {
if(this == obj)
returntrue;
if(obj == null)
returnfalse;
if(getClass() != obj.getClass())
returnfalse;
Person2other = (Person2) obj;
if(age != other.age)
returnfalse;
if(name == null) {
if(other.name != null)
returnfalse;
}else if (!name.equals(other.name))
returnfalse;
returntrue;
}
publicPerson2(String name, int age) {
super();
this.name= name;
this.age= age;
}
}
importjava.util.Comparator;
/**
*Person2 比较器
* @ClassName:Person
* @Description:实现Comparator接口
* @author God
*
*/
public classPersonComparator implements Comparator {
publicint compare(Person2 o1, Person2 o2) {
if(o1.getAge()o2.getAge()){
return1;
}
return0;
}
}
public static void main(String[] args) {
System.out.println("使用Comparator比较器");
Person2p111=new Person2("冬冬", 22);
Person2p222=new Person2("小王", 14);
Person2p333=new Person2("老赵", 42);
Person2p444=new Person2("老李", 41);
Listlist2=new ArrayList();
Collections.addAll(list2,p111,p222,p333,p444);
System.out.println(list2);
Collections.sort(list2,newPersonComparator());
System.out.println(list2);
}
运行结果:
使用Comparator比较器
[冬冬:22, 小王:14, 老赵:42, 老李:41]
[小王:14, 冬冬:22, 老李:41, 老赵:42]
当然也可以写个匿名内部类来实现 Comparator。
public classPerson1 {
privateString name;
privateint age;
publicString getName() {
returnname;
}
publicvoid setName(String name) {
this.name= name;
}
publicint getAge() {
returnage;
}
publicvoid setAge(int age) {
this.age= age;
}
@Override
publicint hashCode() {
finalint prime = 31;
intresult = 1;
result= prime * result + age;
result= prime * result + ((name == null) ? 0 : name.hashCode());
returnresult;
}
@Override
publicboolean equals(Object obj) {
if(this == obj)
returntrue;
if(obj == null)
returnfalse;
if(getClass() != obj.getClass())
returnfalse;
Person1other = (Person1) obj;
if(age != other.age)
returnfalse;
if(name == null) {
if(other.name != null)
returnfalse;
}else if (!name.equals(other.name))
returnfalse;
returntrue;
}
@Override
publicString toString() {
//TODO Auto-generated method stub
returnthis.name + ":" + this.age;
}
publicPerson1(String name, int age) {
super();
this.name= name;
this.age= age;
}
}
测试代码:
public class TestSort {
public static void main(String[]args) {
System.out.println("使用Comparator比较器");
Person1p11=new Person1("冬冬", 22);
Person1p22=new Person1("小王", 14);
Person1p33=new Person1("老赵", 42);
Person1p44=new Person1("老李", 41);
Listlist1=new ArrayList();
Collections.addAll(list1,p11,p22,p33,p44);
System.out.println(list1);
Collections.sort(list1,new Comparator() {
publicint compare(Person1 o1, Person1 o2) {
if(o1.getAge()o2.getAge())
return1;
return0;
}
});
System.out.println(list1);
}
}
运行结果:
使用Comparator比较器
[冬冬:22, 小王:14, 老赵:42, 老李:41]
[小王:14, 冬冬:22, 老李:41, 老赵:42]
当自定义类实现Comparable接口,那么这个类就具有排序功能,Comparable和具体你要进行排序的类的实例邦定(这就好像一个小孩出生开始就会呼吸)。而Comparator比较灵活,它没有和任何类绑定,实现它的自定义类仅仅定义了一种排序方式或排序规则我们的要排序的类可以分别和多个实现Comparator接口的类绑定,从而达到可以按自己的意愿实现按多种方式排序的目的。(这相当于一个小孩出生时没有穿衣服,但是我们给他穿上一件衣服——也就相当于为一个类实例添加排序规则,当然这件衣服也可以脱下来或者换成另一件衣服——这不就像是动态的更换或者去掉排序规则么?)。
最后总结一下:Comparable——“静态绑定排序”,而Comparator——“动态绑定排序”。