zoukankan      html  css  js  c++  java
  • 为什么重写equals一定要重写hashCode方法?

    大家都知道,equals和hashcode是java.lang.Object类的两个重要的方法,在实际应用中常常需要重写这两个方法,但至于为什么重写这两个方法很多人都搞不明白。

    下面我们看下Object类中默认的equals和hashCode方法的实现:

    1     public boolean equals(Object obj) {
    2         return (this == obj);
    3     }
    4 
    5     public native int hashCode();

      

    以上是Object类关于这两个方法的源码,Object类默认的equals比较规则就是比较两个对象的内存地址。而hashcode是本地方法,但实际上,hashcode是根据对象的内存地址经哈希算法得来的。

     1 import lombok.AllArgsConstructor;
     2 import lombok.Data;
     3 
     4 /**
     5  * Created by ganbo on 2019/6/17.
     6  */
     7 
     8 @Data
     9 @AllArgsConstructor
    10 public class User {
    11     private Long id;
    12     private String name;
    13 
    14     @Override
    15     public boolean equals(final Object o) {
    16         if (this == o) return true;
    17         if (!(o instanceof User)) return false;
    18         if (super.equals(o)) return true;
    19 
    20         final User user = (User) o;
    21 
    22         if (id != null ? !id.equals(user.id) : user.id != null) return false;
    23         return name != null ? name.equals(user.name) : user.name == null;
    24     }
    25 
    26     @Override
    27     public int hashCode() {
    28         int result = 1;
    29         result = 31 * result + (id != null ? id.hashCode() : 0);
    30         result = 31 * result + (name != null ? name.hashCode() : 0);
    31         return result;
    32     }
    33 
    }

    上面代码展示了重写equals和hashCode方法后的User类,线有如下代码:

    1     public static void main(String[] args) {
    2         User u1 = new User(1L, "root");
    3         User u2 = new User(1L, "root");
    4 
    5         System.out.println(u1.equals(u2));
    6         System.out.println(u1.hashCode() == u2.hashCode());
    7     }

    此时u1.equals(u2)一定返回true,假如只重写equals而不重写hashCode,那么User类的hashCode方法默认就是继承父类Object的hashCode方法,由于默认的hashCode方法是根据对象的内存地址

    经过hash算法得来的,显然此时u1对象和u2对象的hashCode值不一定相等,这个时候将该对象作为HashMap的key就会出现问题,跟期望的不一致(两个对象equals,却存在MashMap的两个槽上)。

    然而重写了equals,且u1.equals(u2)返回true,根据hashcode的规则,两个对象相等其哈希值一定相等,所以矛盾就产生了,因此重写equals一定要重写hashcode,而且从类重写后的hashcode方法中可以看出,

    重写后返回的新的哈希值与User的两个属性有关。

    以下是关于hashcode的一些规定:

    两个对象相等,hashcode一定相等

    两个对象不等,hashcode不一定不等

    hashcode相等,两个对象不一定相等

    hashcode不等,两个对象一定不等

  • 相关阅读:
    鼠标拖拽UserChromeJS脚本在线生成器
    Firefox书签转按钮UserChromeJS脚本在线生成器
    [原创]Firefox扩展
    F5和CTRL+F5的区别
    玩转log4j
    xml文件报错之Invalid byte 1 of 1byte UTF8 sequence.
    javascript 事件
    jdbc封装类(连接参数配置与web.xml)
    浅谈DHTML
    基于servlet+smartUpload的文件上传
  • 原文地址:https://www.cnblogs.com/ganbo/p/11039053.html
Copyright © 2011-2022 走看看