effective java 第三章对于所有对象都通用的方法

第10条:覆盖equals时请遵守通用约定

不需要重写的场景:

  1. 类的每个实例是唯一的
  2. 类不需要提供逻辑相等的场景
  3. 超类已经重写了equals方法
  4. private类或 缺省类

需要写的规范:

  1. 自反性,自己必须等于自己

  2. 对称性,x.equals(y),那么y.equals(x)

  3. 传递性 ,a.equals(b),b.equals©,那么a.euqals©

  4. a,b 没发生变化,那么 a.equals(b) 多次调用后结果也相同

  5. 对于任何非null值x,必有 x.euqals(y) 为 false;

对称性错误 不能只考虑一边

public class CaseInsensitiveString {
    private final String s;
    public CaseInsensitiveString(String s) {
        this.s = Objects.requireNonNull(s);
    }
    public boolean euqals(String o) {
        if (o.equalsIgnoreCase(s)) {
            return true;
        } else {
            return false;
        }
    }
        public static void main(String[] args) {
        CaseInsensitiveString caseInsensitiveString = new CaseInsensitiveString("AAA");
        String test = "aaa";
        boolean a = caseInsensitiveString.euqals(test);
        boolean b = test.equals(caseInsensitiveString.s);
        System.out.println(a + "  " + b);  //true  false

    }
}

警惕:

  1. 覆盖equals时总要覆盖hashcode
  2. 不要企图让equals方法过于智能, 简单点不容易出错
  3. equals(Object o) 不要写成其他类型的,不然不能重写
第11条:覆盖equals时总要覆盖hashCode
  1. equals方法相等时,hashcode必须相等

  2. 重写hashcode的方法

    2.1 先利用基本数据类型的包装类来获取属性的hashcode再进行组合

    2.2 结果可以用* 31 来进行相加,选31。31便于移位和减法代替乘法

public class PhoneNumber {

    private final short areaCode, prefix, lineNum;

    public PhoneNumber(short areaCode, short prefix, short lineNum) {
        this.areaCode = areaCode;
        this.prefix = prefix;
        this.lineNum = lineNum;
    }
    @Override
    public boolean equals(Object o) {
        if (o.equals(this)) {
            return true;
        } else if (!(o instanceof PhoneNumber)) {
            return false;
        } else {
            PhoneNumber phoneNumber = (PhoneNumber) o;
            return this.areaCode == phoneNumber.areaCode
                    && this.lineNum == phoneNumber.lineNum
                    && this.prefix == phoneNumber.prefix;
        }
    }
    @Override
    public int hashCode() {
        int result = Short.hashCode(areaCode);
        result = result * 31 + Short.hashCode(prefix);
        result = result * 31 + Short.hashCode(lineNum);
        return result;
    }
}
第12条 始终要覆盖toString方法

toString方法能够更方便的去返回想要的信息,对对象来说是一个很简洁的说明;

第13条 谨慎地覆盖clone

clone规范:

对于任意对象x

  1. x.clone() != x 返回true
  2. x.clone().getClass() == x.getClass() 通常返回true
  3. x.clone().equals(x) 通常返回true
第14条 考虑实现Comparable接口
  1. 对称性, x.compareTo(y) == - y.compareTo(x)
  2. 传递性,x.compareTo(y)>0 y.compareTo(z)>0 则 x.compareTo(z)
  3. 强烈建议 (x.compareTo(y) ==0 ) == (x.equals(y))

若要实现排序功能,最好实现Comparable接口,避免使用>或<号,应使用包装类的比较方法,或者使用比较器的构造方法

    private static final Comparator<PhoneNumber> COMPARATOR = Comparator.comparingInt(((PhoneNumber phoneNumber) -> phoneNumber.areaCode))
            .thenComparing(phoneNumber -> phoneNumber.prefix)
            .thenComparing(phoneNumber -> phoneNumber.lineNum);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值