java.lang.Comparable 接口定义的 compareTo() 方法用于提供对其实现类的对象进行整体排序所需要的比较逻辑。
实现类基于 compareTo() 方法的排序被称为自然排序。而 compareTo() 方法的排序被称为它的自然排序。具体的排序原则可由实现类根据需要而定。用户在重写 compareTo() 方法以定制比较逻辑时,需要确保其余等价性判断方法 equals() 保持一致,即 e1.equals((Object)e2) 和e1.compareTo((Object)e2)==0 具有相同的值,这样的话我们就称自然顺序就和 equals 一致。
这个接口有什么用呢?
如果一个数组中的对象实现了 Compareable 接口,则对这个数组进行排序非常简单: Arrays.sort(); 如果 List 实现了该接口的话 , 我们就可以调用Collections.sort 或者 Arrays 方法给他们排序。实际上 Java 平台库中的所有值类 (value
classes) 都实现了 Compareable 接口。
Comparable 接口只有一个方法 compareTo(Object obj)
其中
this <
obj 返回负
this =
obj 返回 0
this >
obj 返回正
即将当前这个对象与指定的对象进行顺序比较,当该对象小于、等于或大于指定对象时,分别返回一个负整数、 0 或正整数,如果无法进行比较,则抛出ClassCastException 异常。
其实,有两种方式可以进行集合排序 :
1. 集合中对象的所属类实现了 java.lang.Comparable 接口
2. 为集合指定比较器 java.lang.Comparator 的实现类
Comparator , Comparable 接口的区别是:
comparable 是通用的接口,用户可以实现它来完成自己特定的比较,而 comparator 可以看成一种算法的实现,在需要容器集合 collection 需要比较功能的时候,来指定这个比较器,这可以看出一种设计模式,将算法和数据分离,就像 C++ STL 中的函数对象一样。
前者应该比较固定,和一个具体类相绑定,而后者比较灵活,它可以被用于各个需要比较功能的类使用。可以说前者属于“静态绑定”,而后者可以“动态绑定”。
一个类实现了 Camparable 接口表明这个类的对象之间是可以相互比较的。如果用数学语言描述的话就是这个类的对象组成的集合中存在一个全序。这样,这个类对象组成的集合就可以使用 Sort 方法排序了。
而 Comparator 的作用有两个:
1. 如果类的设计师没有考虑到 Compare 的问题而没有实现 Comparable 接口,可以通过 Comparator 来实现比较算法进行排序
2. 为了使用不同的排序标准做准备,比如:升序、降序或其他什么序
例如: Person.java 、 TestComparable.java
(1) Person.java
public class Person implements
java.lang.Comparable{
private
final int id;
private
String name;
private
int age;
public
Person(int id,String name,int age){
this.id
= id;
this.name
= name;
this.age
= age;
}
public
int getId(){
return
id;
}
public
void setName(String name){
this.name
= name;
}
public
String getName(){
return
name;
}
public
void setAge(int age){
this.age
= age;
}
public
int getAge(){
return
age;
}
public
String toString(){
return
"Id: " + id + "/tName: " + name + "/tAge: " + age;
}
@Override
public
int compareTo(Object
o){ // 实现 Comparable 接口的抽象方法,定义排序规则
Person
p = (Person)o;
return
this.id -
p.id; // 升序排列,反之降序
}
@Override
public
boolean equals(Object
o){ //equals
boolean
flag = false;
if(o
instanceof Person){
if(this.id
== ((Person)o).id)
flag
= true;
}
return
false;
}
}
(2)
TestComparable.java
import
java.util.TreeSet;
import
java.util.Iterator;
public class
TestComparable{
public
static void main(String[] args) {
TreeSet
ts = new TreeSet();
ts.add(new
Person(1003," 张三 ",15));
ts.add(new
Person(1008," 李四 ",25));
ts.add(new
Person(1015," 王五 ",73));
ts.add(new
Person(1001," 赵六 ",49));
Iterator
it = ts.iterator();
while(it.hasNext()){
Person
employee = (Person)it.next();
System.out.println(employee);
}
}
}
运行结果:
Id:
1001 Name:赵六 Age: 49
Id:
1003 Name:张三 Age: 15
Id:
1008 Name:李四 Age: 25
Id:
1015 Name:王五 Age: 73