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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 1453149997 于 2014-4-5 14:32 编辑



如果按照老师的结论:即“如果元素的hashCode值不同,不会调用equals”,那么请问,集合是怎么知道要插入的元素A的哈希值和集合中的某个元素的哈希值不一样的?
有两种猜想:
(1)调用集合中的每个元素的hashcode的方法,然后用A的哈希值和每个元素的哈希值比较,但是这样的做法效率很低,显然违背了HashSet设计的初衷(即查询效率高)
(2)HashSet被划分为不同的区域,每一段都有一个哈希值来代表;HashSet创建之初,并没有被划分区域,只有有元素存入时,才需要根据元素的哈希值来确定分配存储区域;后续元素插入时,要根据某个哈希值是否存在来确定是否需要分配新的空间;
   如果(1)不成立,那么在HashSet中存在了另一个集合B,用来存储哈希值;当A需要插入时,用A的哈希值和B中的元素比较,可以快速确定是否存在和A哈希值相同的元素,如果有,则调用equals方法和此区域的所有元素比较;如果没有,则HashSet根据哈希值另外分配空间,存储新的元素

请问我的理解合理吗?

评分

参与人数 1技术分 +1 收起 理由
朱神必 + 1

查看全部评分

10 个回复

倒序浏览
本帖最后由 罗安迪 于 2014-4-4 17:42 编辑

1,对于set,存入和取出是无序的,因为他们根据哈希值被存在不同的区域当中。

2,集合B应该理解为 哈希表。就相当于你把元素按哈希值存到了不同的房间,存进去后在同一张纸上写下房间号和存入元素,那么在查找的时候自然就可以直接用表格去查找,而不用进入房间,所以速度快了。

所以你的1和2的理解都是对的~除了调用时查询会慢(事实是会快)。

另外:其次set的底层是map,set集合来自于map。所以在理解上,你完全可以认为

评分

参与人数 1技术分 +1 收起 理由
朱神必 + 1

查看全部评分

回复 使用道具 举报
为什么知道 HashCode 值不同,这不就是让你复写这个功能么,你复写这个功能后,这个相不相同,由你来规定。

评分

参与人数 1技术分 +1 收起 理由
朱神必 + 1

查看全部评分

回复 使用道具 举报
不合理,哈西值是通过hash算法散列运算出来的,。不是保存在一个集合中的。
回复 使用道具 举报
看到你的截图,感觉像是刘意老师总结的是吗
回复 使用道具 举报
不是,是毕向东老师的
回复 使用道具 举报
李洋- 发表于 2014-4-4 19:47
看到你的截图,感觉像是刘意老师总结的是吗

是毕向东老师的
回复 使用道具 举报

你是云九的嘛?
回复 使用道具 举报
李程 中级黑马 2014-4-12 18:54:42
9#
你看下毕老师的讲解和我的理解
11,HashSet心得
对象的地址值相同,那么哈希值一定相同,如果地址值不同,那么哈希值也有可能相同,在哈希值不相同的时候,在HashSet容器中存储的时候就直接存了,如果哈希值相同的时候,就再比较两个对象是否相同,这个时候就是比较两个对象的地址值是否相同了(后面这句话是我自己的猜测,因为equals比较的就是地址,如果复写了equals的话那就另当别论了,总之调用的是equals方法),如果两个对象也相同,那么就不存储,如果对象不同,那么就在同一个哈希值下链式或者顺序存储两个对象。

12,HashSet是如何保证元素唯一性的呢
是通过元素的两个方法,hashCoed和equals来完成:如果元素的HashCode值相同,才会判断equals是否为真;如果元素的HashCode值不相同,才会调用equals,所以建立一个有针对性的HashCode才比较高效。
所以在实际开发过程中,一旦自己定义或者描述一个新的事物,即建立一个类的时候,如果其对象会往集合里面存储,那一般就会复写equals方法和hashCode方法
注意:对于判断元素是否存在,以及删除等操作,依赖的方法是元素的hashCode和equals方法
回复 使用道具 举报
关于这个问题楼主可以看张孝祥老师的基础加强视频-26. 我截了几张图:



回复 使用道具 举报
学习学习!
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马