考虑实现 Comparable 接口

 

compareTo 方法并没有在 Object 类中声明。 相反,它是 Comparable 接口中的唯一方法。 它与 Object 类的 equals 方法在性质上是相似的,除了它允许在简 单的相等比较之外的顺序比较,它是泛型的。 通过实现 Comparable 接口,一个类表明它的实例有一 个自然顺序(natural ordering)。 对实现 Comparable 接口的对象数组排序非常简单,如下所示:

 
 
 
xxxxxxxxxx
 
 
 
 
Arrays.sort(a);  
 

它很容易查找,计算极端数值,以及维护 Comparable 对象集合的自动排序。例如,在下面的代 码中,依赖于 String 类实现了 Comparable 接口,去除命令行参数输入重复的字符串,并按照字母顺 序排序:

 
 
 
xxxxxxxxxx
 
 
 
 
public class WordList {
public static void main(String[] args) {
Set<String> s = new TreeSet<>();
Collections.addAll(s, args);
System.out.println(s);
}
}
 

通过实现 Comparable 接口,可以让你的类与所有依赖此接口的通用算法和集合实现进行互操 作。 只需少量的努力就可以获得巨大的能量。 几乎 Java 平台类库中的所有值类以及所有枚举类型(详 见第 34 条)都实现了 Comparable 接口。 如果你正在编写具有明显自然顺序(如字母顺序,数字顺 序或时间顺序)的值类,则应该实现 Comparable 接口:

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

将此对象与指定的对象按照排序进行比较。 返回值可能为负整数,零或正整数,因为此对象对应小 于,等于或大于指定的对象。 如果指定对象的类型与此对象不能进行比较,则引发 ClassCastException 异常。

实现类必须确保所有 x 和 y 都满足 sgn(x.compareTo(y)) == -sgn(y. compareTo(x)) 。 (这意味着当且仅当 y.compareTo(x) 抛出异常时, x.compareTo(y) 必须抛出异常。) 实现类还必须确保该关系是可传递的: (x. compareTo(y) > 0 && y.compareTo(z) > 0) 意 味着 x.compareTo(z) > 0 。 最后,对于所有的 z,实现类必须确保 x.compareTo(y) == 0 意味着 sgn(x.compareTo(z)) == sgn(y.compareTo(z)) 。 强烈推荐 (x.compareTo(y) == 0) == (x.equals(y)) ,但不是必需的。 一般来说,任何实 现了 Comparable 接口的类违反了这个条件都应该清楚地说明这个事实。 推荐的语言是「注 意:这个类有一个自然顺序,与 equals 不一致」

在 compareTo 方法中,比较属性的顺序而不是相等。 要比较对象引用属性,请递归调用 compareTo 方法。 如果一个属性没有实现 Comparable,或者你需要一个非标准的顺序,那么使用 Comparator 接口。 可以编写自己的比较器或使用现有的比较器,如在条目 10 中的 CaseInsensitiveString 类的 compareTo 方法中:

 
 
 
xxxxxxxxxx
 
 
 
 
// Single-field Comparable with object reference field
public final class CaseInsensitiveString
implements Comparable<CaseInsensitiveString> {
public int compareTo(CaseInsensitiveString cis) {
return String.CASE_INSENSITIVE_ORDER.compare(s, cis.s);
} .
.. // Remainder omitted
}
 

有时,你可能会看到 compareTo 或 compare 方法依赖于两个值之间的差值,如果第一个值小 于第二个值,则为负;如果两个值相等则为零,如果第一个值大于,则为正值。这是一个例子

 
 
 
xxxxxxxxxx
 
 
 
 
// BROKEN difference-based comparator - violates transitivity!
static Comparator<Object> hashCodeOrder = new Comparator<>() {
public int compare(Object o1, Object o2) {
return o1.hashCode() - o2.hashCode();
}
};  
 

不要使用这种技术!它可能会导致整数最大长度溢出和 IEEE 754 浮点运算失真的危险[JLS 15.20.1,15.21.1]。 此外,由此产生的方法不可能比使用上述技术编写的方法快得多。 使用静态 compare 方法:

 
 
 
xxxxxxxxxx
 
 
 
 
// Comparator based on static compare method
static Comparator<Object> hashCodeOrder = new Comparator<>() {
public int compare(Object o1, Object o2) {
return Integer.compare(o1.hashCode(), o2.hashCode());
}
}
 

或者使用 Comparator 的构建方法:

 
 
 
xxxxxxxxxx
 
 
 
 
// Comparator based on Comparator construction method
static Comparator<Object> hashCodeOrder =
Comparator.comparingInt(o -> o.hashCode());
 

猜你喜欢

转载自www.cnblogs.com/lIllIll/p/12624110.html