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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 盖保宁 黑马帝   /  2011-9-27 13:54  /  2622 人查看  /  6 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

看了HashSet  这么多年总算知道哈希表的用武之地了

可是还是那句话,万一哈希值有冲突怎么办

比如北京人口2000万,假设一个人的头发有0到1000万根,肯定会有两个人的头发数目一样

以前知道有这个问题,不知道专家们是怎么解决的啊。

虽然哈希运算不可逆,但是冲突肯定会有的吧

评分

参与人数 1技术分 +1 收起 理由
wangfayin + 1

查看全部评分

6 个回复

倒序浏览
黑马网友  发表于 2011-9-27 14:09:01
沙发
hash值是用来分组的,不是用来作为对象的唯一标示的。
如果任何一个对象都返回一个唯一的值,则这个hash编码是比较失败的。

与hash值相关的是散列技术。散列技术的目的是快速定位对象,即查询效率比线性结构要高。

好比100个人,如果 排成一列,则要确定某一个人的位置,就要成第一个人开始查询,一个个人的来确定所有人的位置。
散列技术就是,把这100个人分成10组,每个组的编号唯一(就相当于是hash码),如果要确定某个人的位置,则只要计算他的hash码,然后根据hash码找到组号,然后与这个组里的10个人比较就行了。

其实,现实世界中的集体与个体关系很多都是散列的,像学生和班级,班级号就是hash码。员工和部门,等等
回复 使用道具 举报
黑马网友  发表于 2011-9-27 14:14:38
藤椅
呵呵,且听我慢慢道来:
HashSet保证元素的唯一性是根据元素的hashCode和equals方法。HashSet集合的底层是哈希表数据结构,哈希表中有哈希值。每一个对象都有自己的hashCode方法算出自己的哈希值,哈希表存储对象时必须使用对象的hashCode方法获取该对象的哈希值来确定该对象在哈希表中的位置。如果hashCode方法算出的值相等则会继续判断两个元素的equals方法是否为true,若为true则表示此时这两个要存储的对象是同一个元素,此时就只会存储这两个对象中的一个,如果equals方法为false则表示这个两个对象不是同一个,此时就会将后一个对象元素加一进行顺延存储到集合中。

评分

参与人数 1技术分 +2 收起 理由
wangfayin + 2

查看全部评分

回复 使用道具 举报
黑马网友  发表于 2011-9-27 14:23:15
板凳
。。HashSet  存元素时。。如果两个元素 hashCode 值相同, equals() 返 回为false,那么存放时,在同一个hashCode 处 就有两个元素了,,
回复 使用道具 举报
黑马网友  发表于 2011-9-27 18:12:13
报纸

回复 沙发 的帖子

有道理,你说     用来分组?  这可能值是咱在java这边用的吧     我说的是广泛的哈希算法——散列表。
哈希可以加密,比如网络通信里的”握手“的实现,都是用的hash运算
回复 使用道具 举报
黑马网友  发表于 2011-9-27 18:26:14
地板

回复 沙发 的帖子

我感觉不对  我认为哈希运算就应该保证唯一性   就算分组也应该不冲突啊  我在矛盾中
回复 使用道具 举报
黑马网友  发表于 2011-9-28 12:04:42
7#
当初上数据结构的时候,就没怎么去过,唉。
查了下数据结构的书《数据结构——用C语言描述》作者:唐策善,李龙澍,黄刘生,P211
散列技术的基本思想是:
以节点的关键字 k  为自变量,通过一个确定的函数关系 f  ,计算出对应的函数值 f(k),把这个值解释为节点的存储地址,将节点存入 f(k)所致的存储位置上。查找时再根据要查找的关键字用同样的函数计算地址,然后到相应的单元里去取要找的节点。用散列法存储的线性表叫散列表(Hash Table),上述的函数 f   称为散列函数,f(k)称为散列地址。
如果散列函数F 对于不相等的关键字key1和key2得到相同的散列地址(F(key1)=F(key2)),该现象称为冲突,发生冲突这两个关键字则称为该散列函数 F 的同义字。
然后说下我的理解。
在原则上来说,我们设计的散列函数 应该返回一个唯一 的值,这是散列表这种结构设计的初衷(不通过比较获得key所对应的地址),每个key对应一个唯一的地址,我拿到key就拿到了地址,不用通过比较就可以获得这个key所对应的值,这样效率是最高的。
但是,现实中,因为key的取值范围一般远远大于表空间的地址集(容量),所以 对于绝大多数 散列函数,产生冲突是在所难免的。
所以,通常散列函数是个多对一的函数,冲突是不可避免的。
因此,就有了处理冲突的方法。主要有两种方法:1 开放地址法 2 拉链法
java中用的就是拉链法。
拉链法解决冲突的做法是:将所有关键字为同义词的节点连接在同一个单链表中。

评分

参与人数 1技术分 +1 收起 理由
wangfayin + 1

查看全部评分

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