前面写了一篇文章是关于comparator的,那么comparable就必须拿出来做了分析对比。
关于这俩个接口的文章也比较多,本文着重从完整的代码示例去展现说明。
OK
首先,还是看下Comparator这里接口的代码:
public interface Comparable<T> {
/**
* Compares this object with the specified object for order. Returns a
* negative integer, zero, or a positive integer as this object is less
* than, equal to, or greater than the specified object.
*
* <p>The implementor must ensure <tt>sgn(x.compareTo(y)) ==
* -sgn(y.compareTo(x))</tt> for all <tt>x</tt> and <tt>y</tt>. (This
* implies that <tt>x.compareTo(y)</tt> must throw an exception iff
* <tt>y.compareTo(x)</tt> throws an exception.)
*
* <p>The implementor must also ensure that the relation is transitive:
* <tt>(x.compareTo(y)>0 && y.compareTo(z)>0)</tt> implies
* <tt>x.compareTo(z)>0</tt>.
*
* <p>Finally, the implementor must ensure that <tt>x.compareTo(y)==0</tt>
* implies that <tt>sgn(x.compareTo(z)) == sgn(y.compareTo(z))</tt>, for
* all <tt>z</tt>.
*
* <p>It is strongly recommended, but <i>not</i> strictly required that
* <tt>(x.compareTo(y)==0) == (x.equals(y))</tt>. Generally speaking, any
* class that implements the <tt>Comparable</tt> interface and violates
* this condition should clearly indicate this fact. The recommended
* language is "Note: this class has a natural ordering that is
* inconsistent with equals."
*
* <p>In the foregoing description, the notation
* <tt>sgn(</tt><i>expression</i><tt>)</tt> designates the mathematical
* <i>signum</i> function, which is defined to return one of <tt>-1</tt>,
* <tt>0</tt>, or <tt>1</tt> according to whether the value of
* <i>expression</i> is negative, zero or positive.
*
* @param o the object to be compared.
* @return a negative integer, zero, or a positive integer as this object
* is less than, equal to, or greater than the specified object.
*
* @throws NullPointerException if the specified object is null
* @throws ClassCastException if the specified object's type prevents it
* from being compared to this object.
*/
public int compareTo(T o);
}
只有一个方法,compareTo(T o),没啥好说的,简单哈
现在,给出实现该接口的一个示例:(注意在其中的注释说明了这俩个接口的用途)
package someTest;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
public class ComparablePerson implements Comparable<Object> {
String firstName,lastName;
Boolean Sex;
Integer age;
public ComparablePerson(String firstName, String lastName,Boolean Sex, Integer age){
this.firstName = firstName;
this.lastName = lastName;
this.Sex = Sex;
this.age = age;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public Boolean getSex() {
return Sex;
}
public Integer getAge() {
return age;
}
//为了输入方便,重写了toString()
public String toString()
{
return firstName +" "+lastName+" "+(Sex.booleanValue()?"男":"女")+" "+age;
}
//定义比较方法
public int compare(Object o1, Object o2){
if (o1 instanceof String) {
return compareImp( (String) o1, (String) o2);
}else if (o1 instanceof Integer) {
return compareImp( (Integer) o1, (Integer) o2);
}else if (o1 instanceof Boolean) {
return compareImp( (Boolean) o1, (Boolean) o2);
}else { //根据需要扩展compare函数
System.err.println("未找到合适的比较器");
return 1;
}
}
//重载
public int compareImp(String o1, String o2) {
String s1 = (String) o1;
String s2 = (String) o2;
int len1 = s1.length();
int len2 = s2.length();
int n = Math.min(len1, len2);
char v1[] = s1.toCharArray();
char v2[] = s2.toCharArray();
int pos = 0;
while (n-- != 0) {
char c1 = v1[pos];
char c2 = v2[pos];
if (c1 != c2) {
return c1 - c2;
}
pos++;
}
return len1 - len2;
}
//重载
public int compareImp(Integer o1, Integer o2) {
int val1 = o1.intValue();
int val2 = o2.intValue();
return (val1 < val2 ? -1 : (val1 == val2 ? 0 : 1));
}
//重载
public int compareImp(Boolean o1, Boolean o2) {
return (o1.equals(o2)? 0 : (o1.booleanValue()==true?1:-1));
}
@Override
public int compareTo(Object o){
ComparablePerson p = (ComparablePerson)o;
String firstname1 = p.getFirstName();
String lastname1 = p.getLastName();
Boolean sex1 = p.getSex();
Integer age1 = p.getAge();
int compareFirstName = compare(this.firstName, firstname1);
int compareLastName = compare(this.lastName, lastname1);
int compareSex = compare(this.Sex, sex1);
if (compareFirstName != 0) {
return compareFirstName;
}
if (compareLastName != 0) {
return compareLastName;
}
if (compareSex != 0) {
return compareSex;
}
return compare(this.age, age1);
}
public static void main(String[] args) {
ComparablePerson p1 = new ComparablePerson("zangwu","gg",false,27);
ComparablePerson p2 = new ComparablePerson("zhangsan","gg",false,21);
int res = p1.compareTo(p2);
/*Returns a
* negative integer, zero, or a positive integer as this object is less
* than, equal to, or greater than the specified object.
*/
System.out.println(res);
/*
* Comparable接口和Comparator接口的不同,就是具体实现方法的不同
* 具体在实现方法中,要根据比较类的那个字段排序,由程序员自己编写
* Comparable接口的特点就是在CompareTo(Object o)方法,如果你是比较的类的编写者,就可以在要排序的类上实现
* 该接口;这就是它的特别之处;
* 在有些情况下,这个类你仅仅能调用,那么你就需要在自己的编写的类上实现Comparator接口,用 int compare(Object o1, Object o2)
* 方法来实现待比较的类实例对象的一个比较。
* 这就是很多人说的Comparable是内部的比较器,Comparator是外部的比较器。*/
ArrayList<ComparablePerson> list = new ArrayList<ComparablePerson>();
// 添加对象到ArrayList中
list.add(new ComparablePerson("ccc", "aaa",true,20));
list.add(new ComparablePerson("AAA","bbb",true,30));
list.add(new ComparablePerson("ccc", "aaa",false,10));
list.add(new ComparablePerson("ccc","aaa",false, 40));
// 打印list的原始序列
System.out.println("排序前:");
for (Iterator<ComparablePerson> iter = list.iterator(); iter.hasNext();){
ComparablePerson Person =(ComparablePerson)iter.next();
System.out.println("before sort=" +Person);
}
// 对list进行排序
// 这里会根据“ComparablePerson实现的Comparable<Object>接口”进行排序,即会根据compareTo(Object o)进行排序
Collections.sort(list);
for (int i = 0; i < list.size(); i++) {
if(i==0)
System.out.println("排序后:");
System.out.println("after sort=" + list.get(i));
}
}
}
个人意见,欢迎交流。