首页 > 代码库 > Comparable与Comparator的区别

Comparable与Comparator的区别

Collections工具类的sort方法有两种重载的形式,第一种要求传入的待排序容器中存放的对象比较实现Comparable接口以实现元素的比较;第二种不强制性的要求容器中的元素必须可比较,但是要求传入第二个参数,参数是Comparator接口的子类型(需要重写compare方法实现元素的比较),相当于一个临时定义的排序规则。

public interface Comparable<T> {
    public int compareTo(T o);
}
public interface Comparator<T> {
    int compare(T o1, T o2);
    boolean equals(Object obj);
}

栗子:

public class Person1 implements Comparable<Person1>
{
    private int age;
    private String name;
  //省略setter,getter
    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);

如果无法进行对其类自身的修改,也修饰词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);

采用了内部类的实现方式,实现compare方法,对类Person2的list进行排序。

对String进行排序,且不区分大小写

 Collections.sort(list, new Comparator<String>()
        {
            @Override
            public int compare(String o1, String o2)
            {
                if(o1 == null || o2 == null)
                    return 0;
                return o1.toUpperCase().compareTo(o2.toUpperCase());
            }
        });

 

 

Comparator接口中定义了两个方法,为什么实现的时候只重写了一个方法?当一个类没有显式继承父类的时候,会有一个默认的父类,即java.lang.Object,在Object类中有一个方法即为equals方法,所以这里并不强制要求实现Comparator接口的类要实现equals方法,直接调用父类的即可,当然也可显式的重写了equals()方法。

 

Comparable 是排序接口;若一个类实现了 Comparable 接口,就意味着 “该类支持排序”。而 Comparator 是比较器;我们若需要控制某个类的次序,可以建立一个 “该类的比较器” 来进行排序。 
??前者应该比较固定,和一个具体类相绑定,而后者比较灵活,它可以被用于各个需要比较功能的类使用。

Comparable与Comparator的区别