zoukankan      html  css  js  c++  java
  • 为什么重写equals时一定要重写hashcode

      我们开发时写一个类,默认继承Object类,Object类的equals方法是比较是否指向同一个对象(地址是否相同),

      

     

     Object类 的hashcode方法返回的对象内存地址的值,

    一个类只重写了equals方法,不重写hashcode,那么对象equals为true(比较内容),但是hashcode为false(因为不同对象,地址不同)

    那么对于hash散列表结构的容器集合,就会出现问题。

    例如:有类Person如下,只重写了equals方法

     1 public class Person{
     2     private int id;
     3     private String name;
     4     
     5     public Person(int id,String name) {
     6         this.id = id;
     7         this.name = name;
     8     }
     9     
    10     public int getId() {
    11         return id;
    12     }
    13     public void setId(int id) {
    14         this.id = id;
    15     }
    16     public String getName() {
    17         return name;
    18     }
    19     public void setName(String name) {
    20         this.name = name;
    21     }
    22     
    23     @Override
    24     public boolean equals(Object obj) {
    25         if (this == obj)
    26             return true;
    27         if (obj == null)
    28             return false;
    29         if (getClass() != obj.getClass())
    30             return false;
    31         Person other = (Person) obj;
    32         if (id != other.id)
    33             return false;
    34         if (name == null) {
    35             if (other.name != null)
    36                 return false;
    37         } else if (!name.equals(other.name))
    38             return false;
    39         return true;
    40     }
    41     
    42 }

    测试如下:

     1 public static void main(String[] args) {
     2         Person p1 = new Person(1,"tom");
     3         Person p2 = new Person(1,"tom");
     4         
     5         System.out.println("p1与p2是否相等:"+p1.equals(p2));
     6         System.out.println("p1 hashcode值:"+p1.hashCode());
     7         System.out.println("p2 hashcode值:"+p2.hashCode());
     8         
     9         // hashset集合值不允许重复
    10         Set<Person> set = new HashSet<>();
    11         set.add(p1);
    12         set.add(p2);
    13         System.out.println(set);
    14     }
    View Code

    运行结果如下:

     因为hashmap,hashset等散列数据结构,会根据hashcode值计算存放在数组中桶的位置,上面两个对象的hashcode不同,所以

    就会存放在数值中的不同位置,这样就会出现一个错误的结果。

    如果重写hashcode方法呢?

    运行结果如下:

    总结:新建一个类,重写equals的同时一定要重写hashcode方法,否则使用散列表数据结构的容器时就会出现问题,

    在重写equals和hashcode后,可以保证equals比较为true,hashcode比较一定为true,但是hashcode相同的两个对象,

    equals不一定相同。

  • 相关阅读:
    vlc的应用之三:动态调用vlc-0.9.4的libvlc.dll【转】
    Linux 下搭建流媒体服务器
    linux bash Shell特殊变量:Shell $0, $#, $*, $@, $?, $$和命令行参数
    lftp mirror 上传目录
    rxvt-unicode配置
    在命令行上 使用 mutt, fetchmail, maildrop, msmtp 收发邮件
    在命令行上 Ubuntu 下使用 mutt 和 msmtp 发送 Gmail 邮件
    git查看各个branch之间的关系图
    在Ubuntu Server是配置iptables防火墙
    Ubuntu 14.04 配置iptables防火墙
  • 原文地址:https://www.cnblogs.com/warrior4236/p/11827463.html
Copyright © 2011-2022 走看看