[Effective Java] (12)考虑实现Comparable接口

  • 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;
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 不像本章讨论的其他方法,compareTo方法不是在Object中声明的。更确切地说,它是Comparable接口...
    tigershin阅读 264评论 0 0
  • compareTo方法并没有在Object中声明。相反,它是Comparable接口中唯一的一个方法。compar...
    郭_4d5f阅读 773评论 0 1
  • 对象的创建与销毁 Item 1: 使用static工厂方法,而不是构造函数创建对象:仅仅是创建对象的方法,并非Fa...
    孙小磊阅读 2,031评论 0 3
  • 请冷静下来, 好好听我说话。 我声音不大,但是我会好好说话 从…… 开始了是吗 好,我简单说一下…… 时间不够了?...
    骤雨将至阅读 141评论 0 0
  • 大师随手写下几十首歌 大师说实在不行就做作词大师 大师把鸡蛋淋上蕃茄酱配上薯片 大师说实在不行就做创意菜大师 大师...
    笑凡chris阅读 183评论 0 0