Java继承中重写equals和hashCode的注意事项

equals方法: 继承中该方法存在以下的问题: 如果子类能够拥有相等的概念, 则覆盖该方法时应该采用getClass方法; 如果由超类决定相等的概念, 那么就可以使用instanceof进行检测, 这样可以在不同的子类之间进行相等的比较.

具体的重写流程:

  • 显式参数使用Object, 命名为otherObject, 稍后可能会进行转换
  • 检测是否是同一对象
    • 第一步判断null
    • 第二步, 判断是否是同一类, 判断类时, 如果时前一种情况, 可以使用isinstance关键字进行判断; 如果是第二种情况, 应该用.class属性和getClass()判断.
    • 如果前面的都相同, 对各个实例的对象域使用equals进行判断, 基本类型域用==进行判断. 数组类型可以使用Arrays.equals方法进行判断.

hashCode方法用于对该类实例进行hash时调用, 如果重写了equals就必须重写该方法, 保证equals相等的两个对象具有相同的hashcode. 编写hashCode方法时, 对于实例域的哈希可以调用它自己的hashCode, 更好的方法是使用Object.hashCode方法避免null引起的问题.

还有更好的办法, 可以调用Object.hash提供所有实例域作为参数, 该方法会调用各个实例域的Object.hashCode并将它们组合起来.

toString方法, 在调用print时会调用该对象的toString方法. 该方法的注意点是, 对于数组对象, 直接使用会输出奇奇怪怪的东西, 正确的方法是对Array对象使用Arrays.toString方法.

使用equals做比较时, 可能需要考虑对比的两个对象有null的情况, 这时应该使用Object.equals方法, 当两者均为null时, 返回true.

总结:

  • equals 相等,hashCode 一定要相等。
  • 重写了 hashCode 也要重写 equals。
  • hashCode 需要保持一致性,状态改变返回的哈希值仍然要一致。
  • equals 的对称、反射、传递等特性。

什么情况要重写hashcode?

默认的Object中equals是基于==实现的, 比较的是二者的id, hashCode通常是返回的对象的id(JVM中的地址).
当重写了equals基于内容相等时, hashcode也需要基于相同的内容进行hash. 例如Student类的equals方法是比较两个对象的学号是否相等, 则hashCode方法也需要重写比如对字符串按照位数加, 或者直接用学号作为其hash(不是一个好的hash 会聚集).

如果hashcode和equals不一致会发生什么?

例如在HashMap中, 是根据key的hash进行rehash, 然后放置, 如果key相同的两次put, hash是不相同的则没法发现该key是已经存在的, 导致HashMap中有两个相同的key.

Java中常用类型的equals和hashCode重写

  1. Integer

    Integer是int的封装类, 它的equals重写为

    public boolean equals(Object obj) {
         
            if (obj instanceof Integer) {
         
                return value == ((Integer)obj).intValue();
            }
            return false;
        }
    

    而这几种整型的hashcode都重写为了自己的基本类型值转int的结果. 例如Integer

    public static int hashCode(int value) {
         
            return value;
        }
    
  2. Short
    Short是short数据

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值