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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 杜佳瑞 中级黑马   /  2012-8-2 20:29  /  2580 人查看  /  7 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

今天学到HashSet这个集合有个疑问:我们在创建对象时,这个hashCode方法到底什么时候调用,视频中老师说windows底层会自动调用hashCode算一个哈希值,问题是这个hashCode一定会执行吗?还是只有在用到HashSet这个集合时才调用。
在实例中,老师复写了父类中的hashCode方法,这样保证每一个相同的对象加入到集合中会返回一个相同的hashCode,继而会进一步调用equals方法比较两个对象内容是否相同,这样就可以保证了Set集合中元素的唯一性,可是这个唯一性是我们自己限制的啊!!如果没有复写父类的hashCode不就会分配一个不同的地址,不会再调用equals进一步比较,这样如果存入对象相同怎么保证唯一呀?(开始老师没复写时候得到的结果就没有保证唯一性)求高手解释一下

评分

参与人数 1技术分 +1 收起 理由
杨志 + 1 加油!

查看全部评分

7 个回复

倒序浏览
hashSet、这个容器是存储的对象是唯一的,不能重复的,保证对象的唯一性根据是调用里面hashCode和里面的equals,这两个方法都是如果没复写的情况下,是调用Object里面。
如果你存入的字符串对象,这你不用担心,他会调用的,因为有Object继承的,如果你存入的自定义对象,没复写里面两个方法,是不能保证数据的唯一性的。
回复 使用道具 举报
如果没有复写父类的hashCode就会分配一个不同的地址,这样已经说明两个元素不同了,就不会再调用equals比较了,刚才我也想到了这个问题,下边是一个兄弟总结的,觉得不错,你也看下
1 哈希算法的原理:
将集合分成若干个存储区域,每个对象可以计算出一个哈希码,可以将哈希码分组,每组对应某个存储区域,根据一个对象的哈希码就可以确定该对象存储在哪个区域。
2 HashSet 集合的工作原理
就是采用哈希算法存取对象的集合,它内部采用对某个数字n进行取余的方式对哈希码进行分组和划分对象的存储区域,HashSet集合在比较的时候先算出对象的哈希值,找到相应的存储区,当然哈希码不同就不用比较了,若相同,然后再取出该区域的每个元素和对象用equals方法进行比较,这样不用遍历集合中的元素就可以得到结论。可见HashSet集合具有很好的对象检索性能。
3  什么时候覆盖HashCode方法?
为了让两个相等的对象也放在相同的区域,那么如果两个对象equals 相等,那么应该让他们的HashCode也相等,达到逻辑上一致,这样就可以在同一个区域进行比较, 防止相等的元素重复存入,当然前提是放在哈希集合中。
希望对楼主对于哈希集合的理解有所帮助

评分

参与人数 1技术分 +1 收起 理由
杨志 + 1 赞一个!

查看全部评分

回复 使用道具 举报
本帖最后由 杜佳瑞 于 2012-8-2 23:16 编辑
郑小杰 发表于 2012-8-2 22:24
如果没有复写父类的hashCode就会分配一个不同的地址,这样已经说明两个元素不同了,就不会再调用equals比较 ...


有点明白了,也就是顶层hashCode只是判断两个对象的地址值是否相同,如果相同的话会进一步equals,如果不同就自动认为是两个不同的对象,即使他们的内容是相同的,就像视频中两个对象都是new出来的会分配不同的值,我试了一些没有复写hashCode,但是我在外面new了一个对象,add了两次,结果就输出了一次,题目的问题是内容一样就当做一个对象,这样就得复写hashCode,进一步equals
还有点疑问:
HashSet会调用hashCode为每个对象分配地址值,那Lisk集合呢,靠什么分配地址值?
回复 使用道具 举报
杜佳瑞 发表于 2012-8-2 23:07
有点明白了,也就是顶层hashCode只是判断两个对象的地址值是否相同,如果相同的话会进一步equals,如果不 ...

hashCode()是Object的方法,Lisk集合应该也是靠hashCode()分配地址值的
回复 使用道具 举报
问题已解决
回复 使用道具 举报
一般来讲,equals这个方法是给用户调用的,如果你想判断2个对象是否相等,你可以重写equals方法,然后在代码中调用,就可以判断他们是否相等了。简单来讲,equals方法主要是用来判断从表面上看或者从内容上看,2个对象是不是相等。举个例子,有个学生类,属性只有姓名和性别,那么我们可以认为只要姓名和性别相等,那么就说这2个对象是相等的。

hashcode方法一般用户不会去调用,比如在hashmap中,由于key是不可以重复的,他在判断key是不是重复的时候就判断了hashcode这个方法,而且也用到了equals方法。这里不可以重复是说equals和hashcode只要有一个不等就可以了!所以简单来讲,hashcode相当于是一个对象的编码,就好像文件中的md5,他和equals不同就在于他返回的是int型的,比较起来不直观。我们一般在覆盖equals的同时也要覆盖hashcode,让他们的逻辑一致。举个例子,还是刚刚的例子,如果姓名和性别相等就算2个对象相等的话,那么hashcode的方法也要返回姓名的hashcode值加上性别的hashcode值,这样从逻辑上,他们就一致了。

要从物理上判断2个对象是否相等,用==就可以了。



多看毕老师视频里面他总结的一些东西~~最好找笔记下来~~~~~~~~~~~~~~

点评

虽然楼主问题已解决,但是我们要发扬记笔记的习惯,更好地复习,所以破例下,加油!  发表于 2012-8-4 09:22

评分

参与人数 1技术分 +1 收起 理由
张_涛 + 1 赞一个!

查看全部评分

回复 使用道具 举报
毕老师的笔记确实总结的很好啊!
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马