一、概述
首先,我们需要知道这两个接口都是用来比较大小的。
二、Comparable 接口
2.1 特点
接口源码如下,我们可以认为它是一个内比较器。
package java.lang;
import java.util.*;
public interface Comparable<T> {
public int compareTo(T o);
}
若一个类实现了 Comparable 接口,那么实现 Comparable 接口的类的对象的 List 列表(或数组)可以通过 Collections.sort(或 Arrays.sort)进行排序。
2.2 举例
如果一个类实现了 Comparable 接口则表明这个类的对象之间是可以相互比较的。如下:
public class Person1 implements Comparable<Person1>
{
private int age;
private String name;
public Person1(String name, int age)
{
this.name = name;
this.age = age;
}
@Override
public int compareTo(Person1 o)
{
return this.age-o.age;
}
@Override
public String toString()
{
return name+":"+age;
}
}
可以看到 Person1 实现了 Comparable 接口中的 compareTo() 方法。实现 Comparable 接口必须修改自身的类,即在自身的类中实现接口中相应的方法,测试代码如下
Person1 person1 = new Person1("zzh",18);
Person1 person2 = new Person1("jj",17);
Person1 person3 = new Person1("qq",19);
List<Person1> list = new ArrayList<>();
list.add(person1);
list.add(person2);
list.add(person3);
System.out.println(list);
Collections.sort(list);
System.out.println(list);
输出结果如下
[zzh:18, jj:17, qq:19]
[jj:17, zzh:18, qq:19]
三、Comparator接口
3.1 特点
接口源码如下,可以认为是一个外比较器。
package java.util;
public interface Comparator<T> {
int compare(T o1, T o2);
boolean equals(Object obj);
}
如果我们的这个类(Person1)无法被修改,如 String,我们又要对其进行排序,当然 String 中已经实现了Comparable 接口。当对类自身无法修改时就用到了 Comparator 接口。
3.2 举例
如 Person2 类,这个类已经固定,无法进行对其类自身的修改,也被 final 修饰了,就不能实现 Comparable 接口了,此时就需要在类的外部使用 Comparator 接口。
public final class Person2
{
private int age;
private String name;
public Person2(String name, int age)
{
this.name = name;
this.age = age;
}
@Override
public String toString()
{
return name+":"+age;
}
测试代码如下:
Person2 p1 = new Person2("zzh",18);
Person2 p2 = new Person2("jj",17);
Person2 p3 = new Person2("qq",19);
List<Person2> list2 = new ArrayList<Person2>();
list2.add(p1);
list2.add(p2);
list2.add(p3);
System.out.println(list2);
Collections.sort(list2,new Comparator<Person2>(){
@Override
public int compare(Person2 o1, Person2 o2)
{
if(o1 == null || o2 == null)
return 0;
return o1.getAge()-o2.getAge();
}
});
System.out.println(list2);
输出结果
[zzh:18, jj:17, qq:19]
[jj:17, zzh:18, qq:19]
这里(public static <T> void sort(List<T> list, Comparator<? super T> c) )采用了内部类的实现方式,实现 compare() 方法,对类 Person2 的 list 进行排序。
四、总结
事实上,Java 平台类库中的所有值类都实现了 Comparable 接口。如果你正在编写一个值类,它具有非常明显的内在排序关系,比如按字母顺序、按数值顺序或者按年代顺序,那你就应该坚决考虑实现这个接口。
compareTo 方法不但允许进行简单的等同性进行比较,而且语序执行顺序比较,除此之外,它与 Object 的 equals 方法具有相似的特征,它还是一个泛型。类实现了 Comparable 接口,就表明它的实例具有内在的排序关系,为实现 Comparable 接口的对象数组进行排序就这么简单: Arrays.sort(a);
Comparable 是排序接口;若一个类实现了 Comparable 接口,就意味着 “该类支持排序”。而 Comparator 是比较器;我们若需要控制某个类的次序,可以建立一个 “该类的比较器” 来进行排序。
前者应该比较固定,和一个具体类相绑定,而后者比较灵活,它可以被用于各个需要比较功能的类使用。可以说前者属于 “静态绑定”,而后者可以 “动态绑定”。
我们不难发现:Comparable 相当于 “内部比较器”,而 Comparator 相当于 “外部比较器”。