面试官问:为什么重写equals() 就一定要重写hashCode() 方法?

导读:本篇文章讲解 面试官问:为什么重写equals() 就一定要重写hashCode() 方法?,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

问题分析

关于这个问题,首先需要深入了解一下 equals 这个方法。

这个 equals 方法是 String 这个类里面的实现。

从代码中可以看到,当调用 equals 比较两个对象的时候,会做两个操作,用==号比较两个对象的内存地址,如果地址相同则返回 true,否则,继续比较字符串的值,如果两个字符串的值完全相等,同样返回 true。

public boolean equals(Object anObject) {
        if (this == anObject){//== :比较内存
            return true;
        }
        if (anObject instanceof String){//比较字符串的值
            String anotherString = (String) anObject;
            int n = value.length;
            if (n == anotherString.value.length){
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0){
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }

equals hashCode()有什么关系呢?

首先,Java 里面任何一个对象都有一个 native hashCode()方法。

其次,这个方法在散列集合中会用到,比如
HashTable

HashMap
这些,当添加元素的时候,需要判断元素是否存在,而如果用
equals
效率太低,所以一般
是直接用对象的
hashCode
的值进行取模运算。
如果
table
中没有该
hashcode
值,它就可以直接存进去,不用再进行任何比较了;
如果存在该
hashcode
值, 就调用它的
equals
方法与新元素进行比较,相同的
话就不存了,不相同就散列其它的地址,所以这里存在一个冲突解决的问题,这
样一来实际调用
equals
方法的次数就大大降低了。
hashCode
的值默认是
JVM
使用随机数来生成的,两个不同的对象,可能生成的
HashCode
会相同。
这种情况在
Hash
表里面就是所谓的哈希冲突,通常会使用链表或者线性探测等方式来解决冲突问题。
但是如果两个完全相同的对象,也就是内存地址指向同一个,那么他们的hashCode
一定是相同的。

了解了 equals hashCode 的关系以后,再来分析这个面试题。

在理论情况下,如果
x.equals(y)==true
,如果没有重写
equals 方法,那么这两对象的内存地址是同一个,意味着
hashCode 必然相等。但是如果我们只重写了
equals
方法,就有可能导致
hashCode 不相同。一旦出现这种情况,就导致这个类无法和所有集合类一起工作。
所以,在实际开发中,约定俗成了一条规则,重写
equals
方法的同时也需要重写hashCode
方法。

回答

如果只重写
equals
方法,不重写
hashCode
方法。
就有可能导致
a.equals(b)
这个表达式成立,但是
hashCode
却不同。
那么这个只重写了
equals
方法的对象,在使用散列集合进行存储的时候就会出现问题。
因为散列结合是使用
hashCode
来计算
key
的存储位置,如果存储两个完全相同的对象,但是有不同的
hashcode
就会导致这两个对象存储在
hash
表的不同
位置,当我们想根据这个对象去获取数据的时候,就会出现一个悖论一个完全相
同的对象会在存储在
hash
表的两个位置,造成大家约定俗成的规则,出现一些
不可预料的错误。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/81341.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!