• 每天一道Java题[3]


    问题

    为什么在重写equals()方法的同时,必须重写hashCode()方法?

       

    解答

    在《每天一道Java题[2]》中,已经对hashCode()能否判断两个对象是否相等做出了解释。equals()方法与hashCode()方法的关系如下:

    1. 如果两个对象的hashCode()返回值不一样,则equals()返回的结果必为false。
    2. 如果两个对象的hashCode()返回值一样的时候,equals()返回的结果未知。
    3. 如果两个对象的equals()返回的结果为true,则两个对象的hashCode()返回值必定相等。
    4. 如果两个对象的equals()返回的结果为false,则两个对象的hashCode()返回值可能不同也可能相同。

    可以看出,equals()与hashCode()有着千丝万缕的关系。简单的说,如果只重写了equals(),没有重写hashCode()的话,因为hashCode()主要用于散列的集合,这就会造成,当使用equals()为true的两个相当的对象作为散列集合中的key时,会得出不一样的结果,这其中原因就是他们的hashCode()返回值不同。

    看下面一个例子:

    package me.huangzijian;
    
    import java.util.HashMap;
    
    public class EqualsAndHashCode {
    
        private String name;
        private int num;
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public int getNum() {
            return num;
        }
        public void setNum(int num) {
            this.num = num;
        }
        public EqualsAndHashCode(String name, int num){
            this.name = name;
            this.num = num;
        }
        @Override
        public boolean equals(Object obj) {
            if(this.name.equals(((EqualsAndHashCode)obj).getName())&&this.num==((EqualsAndHashCode)obj).getNum()){
                return true;
            }
            else{
                return false;
            }
        }
        public static void main(String[] args) {
            EqualsAndHashCode equalsAndHashCode1 = new EqualsAndHashCode("a", 1);
            System.out.println("equalsAndHashCode1's hashCode is: " + equalsAndHashCode1.hashCode());
            HashMap<EqualsAndHashCode, Integer> hashMap = new HashMap<EqualsAndHashCode, Integer>();
            hashMap.put(equalsAndHashCode1, 1);
            EqualsAndHashCode equalsAndHashCode2 = new EqualsAndHashCode("a", 1);
            System.out.println("equalsAndHashCode2's hashCode is: " + equalsAndHashCode2.hashCode());
            System.out.println("equalsAndHashCode1.equals(equalsAndHashCode2) is: " + equalsAndHashCode1.equals(equalsAndHashCode2));
            System.out.println(hashMap.get(equalsAndHashCode2));
        }
    }

    输出的结果:

    equalsAndHashCode1's hashCode is: 1712811212
    equalsAndHashCode2's hashCode is: 1508661727
    equalsAndHashCode1.equals(equalsAndHashCode2) is: true
    null

       

    从中可以看到,equalsAndHashCode1与equalsAndHashCode2的equals()为true,但hashCode()返回值不一样,这就违背了一开始描述的equals()与hashCode()的关系了。而且也可以看出,在HashMap中,也获取不出相同key值(equalsAndHashCode1与equalsAndHashCode2的equals()值为true,则认为是相同的对象)的value值了。

       

    引用

    对于hashCode()与equals()之间的关系,也可以参考《Effective Java》一书中的描述:

    • 在程序执行期间,只要equals方法的比较操作用到的信息没有被修改,那么对这同一个对象调用多次,hashCode方法必须始终如一地返回同一个整数。
    • 如果两个对象根据equals方法比较是相等的,那么调用两个对象的hashCode方法必须返回相同的整数结果。
    • 如果两个对象根据equals方法比较是不等的,则hashCode方法不一定得返回不同的整数。

      

  • 相关阅读:
    【解压缩命令】 -费元星
    【虚拟机取得该虚拟机的所有权失败】--费元星
    solr 常见的问题整理 -费元星
    oracle 建立一个视图,然后授权其他用户访问
    虚拟机安装win7 64位-完美解决-费元星
    solr 学习
    CentOS安装JDK1.7
    Nginx+Tomcat多站点访问默认主页问题-狒狒完美解决-Q9715234
    pip 安装时提示uvloop/loop.c:20:10: fatal error: Python.h解决
    MySQL锁总结
  • 原文地址:https://www.cnblogs.com/huangzijian/p/6858778.html
Copyright © 2020-2023  润新知