Comparable或Comparator

15

1.两者比较

Comparable 是排序接口;若一个类实现了 Comparable 接口,就意味着 “该类支持排序”。

Comparator 是比较器;我们若需要控制某个类的次序,可以建立一个 “该类的比较器” 来进行排序。

Comparable 相当于 “内部比较器”,而 Comparator 相当于 “外部比较器”。

2.自然排序Comparable

Comparable的定义:

public interface Comparable<T> {
    public int compareTo(T o);
}

Comparable对实现它的每个类的对象进行整体排序。这个接口需要类本身去实现。

public class Person1 implements Comparable<Person1>
{
    private int age;
    private String name;

    @Override
    public int compareTo(Person1 o)
    {
        return this.age-o.age;
    }
}
重写compareTo() 的规则: 
如果当前对象this大于形参对象obj,则返回正整数,
如果当前对象this小于形参对象obj,则返回负整数,
如果当前对象this等于形参对象obj,则返回零。

可以通过 Collections.sort(或 Arrays.sort)进行排序

        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);
        Collections.sort(list);

2.定制排序Comparator

当元素的类型没有实现java.lang.Comparable接口而又不方便修改代码, 或者实现了java.Lang.Comparable接口的排序规则不适合当前的操作, 那么可以考虑使用Comparator的对象来排序。

Comparator的定义:

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

一个类没有显式继承父类的时候,会有一个默认的父类,即java.lang.Object,在Object类中有一个方法即为equals方法,所以这里并不强制要求实现Comparator接口的类要实现equals方法,直接调用父类的即可。

 @Test
    public void test3(){
        String[] arr = new String[]{"AA","DD","CC"};
        //按照字符串从大到小的顺序排列
        Arrays.sort(arr, new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                if (o1 instanceof String && o2 instanceof String){
                    return -o1.compareTo(o2);//从大到小
                }
                throw new RuntimeException("传入的数据类型不一致");
            }
        });
        System.out.println(Arrays.toString(arr));
    }
重写compare(Object o1, object 02)方法,比较o1 和o2的大小:
如果方法返回正整数,则表示o1大于o2;
如果返回e,表示相等;
返回负整数,表示o1 小于o2。
public class ComparatorTest {
    public static void main(String[] args) {
        //实现字符串按照长度排序,如果长度相同,按照编码排序
        TreeSet<String> set = new TreeSet<>(new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                int n = o1.length() - o2.length();
                if (n == 0) {
                    //compareTo 按照编码表顺序来比较的
                    return o1.compareTo(o2);
                }
                return n;
            }
        });
        set.add("beijing");
        set.add("hello");
        set.add("hella");
        set.add("shangdong");
        System.out.println(set.toString());
    }
}