Comparable与Comparator

Comparable

Arrays类中的sort方法,可以对对象数组进行排序,但有个前提条件,该对象需要实现Comparable接口。该接口建议compareTo方法应该和equals方法兼容。也就是说,当x.equals(y)时x.compareTo(y)就应该等于0。

package com.studyjava.demo;

import java.util.Objects;

class Employee implements Comparable
{
    ......

    public int compareTo (Object otherObj)
    {
        Employee other = (Employee) otherObj;

        return Double.compare(this.salary, other.salary);
    } 
}

这里,我们使用Double类的静态方法compare来比较两个double数。若两个数相等则返回0,第一个数大于第二个数时,返回一个大于0的数,否则返回一个小于0的数。

注意,这里为什么没有使用

return this.salary - other.salary;

因为两个浮点数相近都又不相等的时候,差值经过四舍五入很可能变为0。

Comparator

我们已经知道如何对一个对象数组进行排序,前提是这些对象是实现了Comparable接口类的实例。例如可以对一个字符串数组排序,因为String类实现了Comparable,而且String.compareTo方法可以按字典顺序比较字符串。

现在假设我们希望按长度递增的顺序对字符串进行排序,而不是按字典顺序进行排序。肯定不能让String类用两种不同的方式实现compareTo方法——更何况,String类也不应由我们来修改。

要处理这种情况,Arrays.sort方法还有第二个版本,有一个数组和一个比较器作为参数,比较器是实现了Comparator接口类的实例。

public interface Comparator<T>
{
    int compare(T first, T second);
}

要按长度比较字符串,可以如下定义一个实现Comparator的类:

package com.studyjava.demo;

import java.util.Comparator;
import java.util.Arrays;

public class Demo12
{
    public static void main (String[] args)
    {
        String[] names = {"paul", "James", "Wade", "Bryant"};

        Arrays.sort(names, new CompareByLen());
        System.out.println(Arrays.toString(names));
    }
}

class CompareByLen implements Comparator<String>
{
    public int compare (String s1, String s2)
    {
        return s1.length() - s2.length();
    }
}