码迷,mamicode.com
首页 > 编程语言 > 详细

JAVA-初步认识-常用对象API(集合框架-哈希表2)

时间:2018-01-17 13:46:18      阅读:195      评论:0      收藏:0      [点我收藏+]

标签:直接   地址   bsp   hash   存在   pos   做了   api   哈希表   

一.

哈希表中判断元素是否相同的方式到底是什么?我们要探索一下。

刚才我们存储ab的时候,表中已经有ab了。再往里面存储ab的时候,首先要放入算法中计算地址。一算完,这个地址是5,然后到表中去寻找,发现5的位置上已经有元素了。接下来就不往里面存了么?不一定,我们只能说这个位置上已经有元素了,不能保证这个元素是ab。我有两个元素算出来的地址都是5,不能因此就判断这个元素就是相同的。

技术分享图片

举例来看,ab和ba,这两个字符串是不一样的,通过哈希算法得到的结果是一致的。它们的位置一样,但是内容是不相同的。

在哈希表中,必须不能有重复的,那涉及一个问题,哈希表是如何确定元素是重复的呢?光凭哈希算法的结果不完全准。先看值,后判断。

不是说哈希值得出的结果相同,就是同一元素,毕竟是转借了一个过程,通过这个过程得到的相同,和直接判定相同是两回事。

如果哈希值都不相同,那就不存在第二步的判断内容了。

技术分享图片

现在讲一下哈希表中特殊的东西,当哈希值相同时,内容不相同,那么就需要存储,这就是哈希冲突(哈希值一样)。两个对象一样,但是哈希值不一样。

这种情况不多,因为一般哈希算法比较复杂。

这种情况是有的,解决的措施不唯一,比如说顺延。万一顺延到后面没位置怎么办呢?将数组长度延长,或者串联。

串联比较有趣,位置是5,挂一个出来,如下图所示。这种串联它会继续算它的位置,是基于5来算的。

技术分享图片

体系中有很多方式来存储这样的元素,而这些元素本身也有自己的规则和位置。(不可能说,两个哈希值一样,内容不一样,就直接覆盖掉,没有那么理想化)

不用担心,直接用算法来实现就可以了。

我们担心是这件事情,如果我想在这个数组中去查询到底有没有ba,首先到算法中去计算,得到一个位置。算到这个位置后,就到这个位置上去寻找这个元素。

和它一样吗?先比较ab,发现不一样,但是这个位置上不止一个元素,再往下找ba,发现有,这时候就不存了。这是它内部产生的规律,并 不冲突。

(其实我比较好奇,哈希冲突,尤其是这样挂着的形式,在内存中是怎样的体现形式?)

搞定完以后,现在回头来说一下,如果我们想要搞定哈希表,往里面存这样的对象,我们要注意hashcode和equals方法,观看原先的例子。

往哈希表中存储的是字符串,在存储的时候,就采用了hashcode方法。

技术分享图片

我们来看一下字符串的hashcode方法是什么样的。找到String类,它本身就覆盖了object类中的hashcode方法,这个方法定义了字符串中的哈希码,或者说哈希算法,同时也覆盖了object中的equals方法,定义了自己的判断内容是否相同的依据。

技术分享图片

技术分享图片

接下来我们看一下,它到底是怎么完成的。打开String的源码,左侧的outline是大纲视窗,这里面列出了当前类里面的所有成员,这样寻找起来比较方便。

技术分享图片

找到hashcode,下图显示的就是字符串哈希算法。它怎么算的,不用管,它是根据字符串自身的特点来计算的。

技术分享图片

技术分享图片

这里的value,其实是字符串对应的数组。

再看它的equals,它也是在判断其中的每一位。体系本身已经做了hashcode和equals的定义。

技术分享图片

到目前为止讲述了这么多,要说一件重要的事儿,往里面存储一些自定义对象。

 

JAVA-初步认识-常用对象API(集合框架-哈希表2)

标签:直接   地址   bsp   hash   存在   pos   做了   api   哈希表   

原文地址:https://www.cnblogs.com/wsw-bk/p/8301389.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!