第12条:考虑实现Comparable接口

第12条:考虑实现Comparable接口

如果一个类实现了Comparable接口,就代表着它的实例具有内在的排序关系。

先来看看Comparable接口:

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

可以看到,Comparable接口中只有compareTo一个方法,这个方法不但允许进行等同性比较,而且可以进行顺序比较。如果你正在编写一个具有明显内在排序关系的值类,那就应该坚决考虑实现这个接口。

compareTo方法的通用约定:

将这个对象与指定的对象相比较。当该对象小于,等于或大于指定对象时,分别返回一个负整数,零或正整数。如果由于指定对象的类型而无法与该对象进行比较,则抛出ClassCastException异常。

就如同违反了hashCode约定的类会破坏其它的依赖于散列的类一样(参照第9条),违反compareTo约定的类也会破坏其它带有排序关系的类,如TreeSet和TreeMap。

还有一点值得注意,书中强烈建议(x.compareTo(y)==0)==(x.equals(y)),因为如果不这么做,会导致这个类在不同的集合中有不同的表现。例如在BigDecimal类中:

BigDecimal bigDecimal1=new BigDecimal("1.0");
BigDecimal bigDecimal2=new BigDecimal("1.00");
System.out.println(bigDecimal1.equals(bigDecimal2));    //false
System.out.println(bigDecimal1.compareTo(bigDecimal2));     //0

由上可见在BigDecimal类中equals方法与compareTo方法表现不一致,若将这两个BigDecimal对象加入HashSet中,这个集合将包含两个元素,因为HashSet是基于equals方法的。但是将这两个对象加入TreeSet方法中,则在集合中只有一个元素,因为TreeSet是基于compareTo方法的。

如果一个类有多个应该比较的域,那么可以最重要的域开始,按照重要性由高到低逐步进行到所有需要比较的域。如果一个域中产生了非零的结果,则比较过程结束,直接返回该结果。若所有域中都相等,那么比较的两个对象就是相等的。例如:

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;
}

当这么做的时候,需要注意可能返回的最大和最小值应该在INTEGER.MAX_VALUE和INTEGER.MIN_VALUE之间,否则可能会产生溢出,返回错误的结果。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值