老师请问为什么equals方法在重写时,hashCode方法为什么也建议重写呢?该怎么重写呢?

老师请问为什么equals方法在重写时,hashCode方法为什么也建议重写呢?该怎么重写呢?

在API文档中equals()方法中这样写的:当equals方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码。这句话不太懂老师

正在回答

登陆购买课程后可参与讨论,去登陆

3回答

同学你好,可以这样理解,

1、对于第一个问题,该类中如果只重写hashCode()方法后,toString()输出的对象信息为什么一模一样啊(后面的地址也一样),但是此时调用equals()时仍然是false。

这里同学首先要分清,hashCode()方法是通过将该对象的内部地址转换成一个整数,并不是地址本身,而是对象在hash表中的地址, 而本身对象的地址是不可变的,两者不是一个!toString()输出的对象信息是调用重写后的hashcode()方法,也就是对象在hash表中的地址,所以输出的一致。而equals()返回false是因为equls()方法没有重写,相当于==,也就是比较本身对象的地址,而本身在内存中的地址是不可变的,所以仍然是false。

2、对于第二个问题,hashCode()方法为什么会影响到toString()方法后面对象地址的输出? 

因为hashCode()方法被重写了,toString()方法也就是调用重写后的对象在hash表中的地址,所以会影响。

如果我的回答解决了你的疑惑,请采纳!祝学习愉快!

  • qq_旧安_0 提问者 #1
    好的,我明白了,谢谢老师的耐心解答!
    2019-11-05 18:59:52
好帮手慕酷酷 2019-11-05 15:30:08

同学你好,

1、老师这里所描述的地址是指,在没有重写hashcode()方法时,也就是Object默认的hashcode方法的值是对象的内存地址,是由JDk底层代码实现的。

2、重写后的hashcode()是根据属性进行计算的。这里prime=31;是为了方便来计算散列结果,而设置的值。

3、与equals()方法的关系,老师在上面有讲到,因为两个对象相等其哈希值一定相等,所以要保证两个对象的hashcode方法的值相等。

4、源码里面object类的方法,public native int hashCode(); native 类型是Java本地接口,因为Java语言的实现是基于C++语言实现的,所以这里native 类型,其实是调用的底层C++代码实现的地址值,我们是看不到C++代码的哦。

如果我的回答解决了你的疑惑,请采纳!祝学习愉快!

  • 提问者 qq_旧安_0 #1
    老师您好,该类中如果只重写hashCode()方法后,toString()输出的对象信息为什么一模一样啊(后面的地址也一样),但是此时调用equals()时仍然是false。hashCode()方法为什么会影响到toString()方法后面对象地址的输出? 结果(输出分别是one、one.hashCode()、two.toString()、two.hashCode()、one.equals(two)、one==two): 1.只重写hashCode方法,不重写equals时结果如下: hashCodeTest.HashCodeAndEquals@be05a 778330 hashCodeTest.HashCodeAndEquals@be05a 778330 false false 2.hashCode方法和equals方法均重写时结果如下: hashCodeTest.HashCodeAndEquals@be05a 778330 hashCodeTest.HashCodeAndEquals@be05a 778330 true false
    2019-11-05 16:28:23
好帮手慕酷酷 2019-11-05 13:00:52

同学你好,关于hashcode的讲解在后面的课程中会有更详细的讲解视频,这里老师简单说一下

1、例如现在有两个Student对象,重写equals()方法:

    Student s1=new Student("小明",18);

    Student s2=new Student("小明",18);

此时s1.equals(s2)一定返回true

假如只重写equals而不重写hashcode,那么Student类的hashcode方法就是Object默认的hashcode方法,由于默认的hashcode方法是根据对象的内存地址得来的,s1和s2是new的两个对象,在内存中的地址不同,故两者的hashcode不一定相等。

而重写了equals,且s1.equals(s2)返回true,根据hashcode的规则,两个对象相等其哈希值一定相等,所以矛盾就产生了,因此重写equals建议要重写hashcode。

2、重写hashcode():可以直接使用编译器Eclipse自动生成,不需要手动编写,右键-Source——Generate hashCode and equals... Eclipse就会自动生成啦~

如果我的回答解决了你的疑惑,请采纳!祝学习愉快!

  • 提问者 qq_旧安_0 #1
    老师您好,重写hashcode()编译器自动生成的代码如下: public int hashCode() { final int prime = 31; int result = 1; result = prime * result + number; result = prime * result + score; result = prime * result + ((type == null) ? 0 : type.hashCode()); return result; } 该类中属性如下://定义属性 int number; int score; String type; 老师重写的方法中并没有用到地址啊,它跟equals有什么关系?它的prime=31;是什么?源码里面object类的方法 hashCode方法只有 public native int hashCode();这一句话,是怎么根据地址生成哈希值的啊老师
    2019-11-05 14:12:40
问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星
请稍等 ...
意见反馈 帮助中心 APP下载
官方微信

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师