Comparable接口定义如下:
public interface Comparable<T>{
publci int compareTo(T o);
}
接口里就一个compareTo方法,当对象大于指定对象时返回正整数,等于时返回零,小于时返回负整数。
java包装类都实现了Comparable接口,当前对象与参数对象进行比较,在小于、等于、大于参数时,应分别返回-1、0、1。各个包装类的实现基本都是根据基本类型值进行比较。对于Boolean,false小于true。对于Float和Double,存在和equals方法一样的问题,0.01和0.1*0.1相比的结果并不为0。1
在TreeSet集合中,当存储对象时要求该类必须实现Comparable接口,并重写compareTo()方法,然后TreeSet集合就会对该类型元素使用compareTo()方法进行比较,并默认进行升序排序。
//定义Teacher类实现Comparable接口
public class Teacher implements Comparable{
String nanme;
int age;
public Teacher(String name,int age){
this.name=name;
this.age=age;
}
public String toString(){
return name+":"+age;
}
//重写Comparable接口的compareTo()方法
public int compareTo(Object obj){
Teacher s = (Teacher)obj;
//定义比较方式,先比较年龄age,再比较姓名name
if(this.age-s.age>0){
return 1;
}
if(this.age-s.age==0){
return this.name.compareTo(s.name);
}
return -1;
}
}
public class Test{
public static void main(String args[]){
TreeSet ts = new TreeSet();
ts.add(new Teacher("Jack",19);
ts.add(new Teacher("Rose",18);
ts.add(new Teacher("Tom",19);
ts.add(new Teacher("Rose",18);
System.out.println(ts);
}
}
输出结果如下:
[Rose:18,Jack:19,Tom:19]
Teacher类实现了Comparable接口,并重写了compareTo()方法。在compareTo()方法中,首先对age的值进行比较,根据比较结果返回-1和1,当age相同时,在对name进行比较。TreeSet集合会将重复的元素去掉。2
上面代码调用了String类的compareTo()方法,其源码如下:
public int compareTo(String anotherString) {
int len1 = value.length;
int len2 = anotherString.value.length;
int lim = Math.min(len1, len2);
char v1[] = value;
char v2[] = anotherString.value;
int k = 0;
while (k < lim) {
char c1 = v1[k];
char c2 = v2[k];
if (c1 != c2) {
return c1 - c2;
}
k++;
}
return len1 - len2;
}
该方法比较规则: 选取两者最短的长度,先进行两者的第一个字符的比较(按ASCII码比较),如果不等返回ASCII码之差,如果前面比较都相同则返回两者长度之差。