A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 张学永 于 2012-11-13 18:34 编辑

如果我定义了一个类,只覆写了HashCode方法,而没有覆写equals方法。现在有两个类的对象,它们的哈希值相等,
现在如果把这个类的对象放入HashSet集合中,已知覆写得到的它们的哈希值相等,那它们再进行equals比较的时候,
用的是Object的equals方法吗?此时比较的是什么呢?是比较两个对象的内存地址值是否相等么?这个内存地址值是哈希值吗?
如果是的话,这个哈希值和自定义得到的哈希值有什么关联呢???求解。。。

评分

参与人数 1技术分 +1 收起 理由
古银平 + 1 赞一个!

查看全部评分

13 个回复

倒序浏览
如果没有覆写这个类的equals()方法的话,那么调用的就是Object的equals()方法,此时比较的就是两个对象的内存地址的哈希值是否相等,因为equals()方法的比较判断就是通过该类的HashCode()方法进行比较,而你重写了HashCode()方法,没有重写equals()方法,所以equals()比较的就是你重写的HashCode()方法里计算的哈希值.

点评

object 中的equals和==是一样的  发表于 2012-11-13 15:52
回复 使用道具 举报
黑马_宋超 发表于 2012-11-13 14:46
如果没有覆写这个类的equals()方法的话,那么调用的就是Object的equals()方法,此时比较的就是两个对象的内存 ...

那这两个对象岂不是相等了么?哈希值相等,equals也相等,那它们岂不是只能存进一个在Set集合里面?
回复 使用道具 举报
张学永 发表于 2012-11-13 14:50
那这两个对象岂不是相等了么?哈希值相等,equals也相等,那它们岂不是只能存进一个在Set集合里面? ...

是啊,所以自定义类需要同时重写HashCode()方法和equals()方法
回复 使用道具 举报
如果你复写了hashCode(),没有复写equals(),那么在两个对象哈希值相同然后调用equals()方法时,比较的地址就是由你复写的hashCode()方法得到的哈希值。
回复 使用道具 举报
黑马_宋超 发表于 2012-11-13 14:53
是啊,所以自定义类需要同时重写HashCode()方法和equals()方法

可是,我试验过,这种情况,两个对象覆写的哈希值相等,是可以存进两个去的,说明此时equals方法比较的不是自身覆写的哈希值。
回复 使用道具 举报
本帖最后由 黑马_宋超 于 2012-11-13 15:11 编辑
张学永 发表于 2012-11-13 14:54
可是,我试验过,这种情况,两个对象覆写的哈希值相等,是可以存进两个去的,说明此时equals方法比较的不 ...

貌似我错了,不好意思,Object里的equals()方法在判断完哈希值之后还要再判断两个对象是否相同是否是同一个对象,所以没有覆写equals()方法可以存进去两个
回复 使用道具 举报
黑马_宋超 发表于 2012-11-13 15:10
貌似我错了,Object里的equals()方法在判断完哈希值之后还要再判断两个对象是否相同是同一个对象,所以没有 ...

判断是否是同一个对象,又比较的是什么呢?应该是内存地址值吧?这个和哈希值又有啥关系呢?如果比较的是我覆写的哈希值,那它们不是同一个对象吗?所以我觉得比较的应该是Object方法的equals方法,貌似Object的equals方法调用的是Object自己的hashcode方法,这个hashcode方法应该是电脑内存分配的哈希值,而不是我覆写的hashcode方法得到的哈希值,所以他们的equals才不会相等。不知道我分析的对不对。。。
回复 使用道具 举报
张学永 发表于 2012-11-13 15:15
判断是否是同一个对象,又比较的是什么呢?应该是内存地址值吧?这个和哈希值又有啥关系呢?如果比较的是 ...

应该不是这样,因为你已经重写也就是覆盖掉了Object中的HashCode()方法,我刚百度了下,貌似是因为equals()比较的对象在内存中的地址,而HashCode()并不是代码对象在内存中的真正地址,只是按照对象在内存中的地址计算而来的一个值,所以你重写了HashCode()后,所以他们的哈希值相等了,但是两个对象在内存中的地址还是不同,所以equals()判断为两个不同的对象
回复 使用道具 举报
黑马_宋超 发表于 2012-11-13 15:28
应该不是这样,因为你已经重写也就是覆盖掉了Object中的HashCode()方法,我刚百度了下,貌似是因为equals() ...

Object的equals方法的底层原理不是调用Object的hashCode()方法么?Object的hashCode()方法比较的不是内存真正的地址值么?求解
回复 使用道具 举报
张学永 发表于 2012-11-13 15:33
Object的equals方法的底层原理不是调用Object的hashCode()方法么?Object的hashCode()方法比较的不是内存 ...

equals的底层调用的是"==",刚看下下源码,Object里的equals()的源码是这样的
public boolean equals(Object obj) {
        return (this == obj);
    }
回复 使用道具 举报
黑马_宋超 发表于 2012-11-13 15:38
equals的底层调用的是"==",刚看下下源码,Object里的equals()的源码是这样的
public boolean equals(Objec ...

也就是说==才是判断的真正的内存地址,而Object的hashCode()算出的哈希值只是根据内存地址算出的一个结果了???
回复 使用道具 举报
张学永 发表于 2012-11-13 15:41
也就是说==才是判断的真正的内存地址,而Object的hashCode()算出的哈希值只是根据内存地址算出的一个结果 ...

嗯,应该就是这样了
回复 使用道具 举报
刘菲 中级黑马 2012-11-13 16:32:49
14#
1.hashSet集合是通过集合的两个方法,hashCode和equals来保证元素唯一性的。
2.如果元素的hashCode值相等,才会判断equals是否为true,如果为true则不会将这个元素存入。
如果元素的hashCode值不同,则不会调用equals方法,直接将元素存入。
3.如果没有对hashCode和equals方法进行覆写,那么默认就会调用Object中的这两个方法。
4.Object中的equals方法比较的是内存地址。
  因为你说的是两个类对象,所以他们所分配的空间不同,内存地址值也就不同。在比较时会认为是不同的元素。
5.如果根据 equals(Object) 方法,两个对象是相等的,那么对这两个对象中的每个对象调用 hashCode 方法都必须生成相同的整数结果。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马