- Comparable接口中的唯一的方法是compareTo,其不仅可以进行简单的同性比较,而且允许顺序比较。与equals方法具有相似的特征特征,但compareTo方法并没有在Object中声明。
- 如果一个类实现了Comparable接口,表明该实例具有内在的排序关系(natural ordering).
1. compareTo的通用约定
- 当将这个对象与指定对象进行比较时,当该对象小于、等于或大于指定对象的时候,分别返回一个负整数、零或正整数;
- 如果由于指定的对象的类型而无法与对象进行比较,则抛出ClassCastException异常;
- agn(x.compareTo(y)) == -sgn(y.compareTo(y))(自反性),并且前者抛出异常时,后者才抛出异常;
- (x.compareTo(y) > 0 && y.compareTo(z) > 0)则(x.compareTo(z) > 0)(传递性)
- 如果x.compareTo(y) == 0,则所有的z都满足sgn(x.compareTo(z)) == sgn(y.compareTo(z));
- 若compareTo方法与equals方法的比较结果不同则需在文档中注明。
2. compareTo与equals不同
- 在跨越不同的类的时候,compareTo可以不做比较:如果两个被比较的对象引用不同的类对象,compareTo可以抛出ClassCastException异常。
3. 为实现Compareable接口的类增加值组件
- 可参考equals方法扩展值组件的权宜之计:采用复合优先于继承的方式,不在让类B扩展类A,而是在类B中加入一个私有的A域。
4. 代码演示
- 从重要的域开始,逐步进行到所有的重要域,代码如下:
class PhoneNumber implements Compareable{
private final short areaCode;
private final short prefix;
private final short lineNumber;
···
public int compareTo(PhoneNumber pn) {
// compare areaCode
if (areaCode < pn.areaCode) {
return -1;
}
if (areaCode > pn.areaCode) {
return 1;
}
// areaCode are equal, compare prefixes
if (prefix < pn,prefix) {
return -1;
}
if (prefix > pn,prefix) {
return 1;
}
// areaCode and prefixes are equal, compare lineNumbers
if (lineNumber < pn.lineNumber) {
return -1;
}
if (lineNumber > pn.lineNumber) {
return 1;
}
return 0;
}
}
若程序中为了简便写成如下形式,注意溢出的问题
public int compareTo(PhoneNumber pn) {
int areaCodeDiff = areaCode - pn.areaCode;
if (areaCodeDiff != 0) {
return areaCodeDIff;
}
int prefixDiff = prefix - pn.prefix;
if (prefixDiff != 0) {
return prefixDIff;
}
return lineNumber - pn.lineNumber;
}