黑马程序员技术交流社区

标题: hashCode算法 [打印本页]

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

作者: 朱烈葵    时间: 2012-8-2 20:57
hashSet、这个容器是存储的对象是唯一的,不能重复的,保证对象的唯一性根据是调用里面hashCode和里面的equals,这两个方法都是如果没复写的情况下,是调用Object里面。
如果你存入的字符串对象,这你不用担心,他会调用的,因为有Object继承的,如果你存入的自定义对象,没复写里面两个方法,是不能保证数据的唯一性的。
作者: 郑小杰    时间: 2012-8-2 22:24
如果没有复写父类的hashCode就会分配一个不同的地址,这样已经说明两个元素不同了,就不会再调用equals比较了,刚才我也想到了这个问题,下边是一个兄弟总结的,觉得不错,你也看下
1 哈希算法的原理:
将集合分成若干个存储区域,每个对象可以计算出一个哈希码,可以将哈希码分组,每组对应某个存储区域,根据一个对象的哈希码就可以确定该对象存储在哪个区域。
2 HashSet 集合的工作原理
就是采用哈希算法存取对象的集合,它内部采用对某个数字n进行取余的方式对哈希码进行分组和划分对象的存储区域,HashSet集合在比较的时候先算出对象的哈希值,找到相应的存储区,当然哈希码不同就不用比较了,若相同,然后再取出该区域的每个元素和对象用equals方法进行比较,这样不用遍历集合中的元素就可以得到结论。可见HashSet集合具有很好的对象检索性能。
3  什么时候覆盖HashCode方法?
为了让两个相等的对象也放在相同的区域,那么如果两个对象equals 相等,那么应该让他们的HashCode也相等,达到逻辑上一致,这样就可以在同一个区域进行比较, 防止相等的元素重复存入,当然前提是放在哈希集合中。
希望对楼主对于哈希集合的理解有所帮助
作者: 杜佳瑞    时间: 2012-8-2 23:07
本帖最后由 杜佳瑞 于 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-3 10:38
杜佳瑞 发表于 2012-8-2 23:07
有点明白了,也就是顶层hashCode只是判断两个对象的地址值是否相同,如果相同的话会进一步equals,如果不 ...

hashCode()是Object的方法,Lisk集合应该也是靠hashCode()分配地址值的
作者: 杜佳瑞    时间: 2012-8-3 21:38
问题已解决
作者: 官文昌    时间: 2012-8-3 21:59
一般来讲,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 02:49
毕老师的笔记确实总结的很好啊!




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2