当前位置: 首页 > news >正文

企业内部管理系统网站建设苏州推广排名

企业内部管理系统网站建设,苏州推广排名,公司建设网站方案,高端大气网站源码目录导航哈希函数的作用与本质哈希函数设计哈希表初始容量的校正哈希表容量为2的整数次幂的缺陷及解决办法注:为了简化代码,提高语义,本文将HashMap很多核心代码抽出并根据代码含义为代码片段取名,完全是为了方便读者理解。哈希函…

目录导航

    • 哈希函数的作用与本质
    • 哈希函数设计
    • 哈希表初始容量的校正
    • 哈希表容量为2的整数次幂的缺陷及解决办法

注:为了简化代码,提高语义,本文将HashMap很多核心代码抽出并根据代码含义为代码片段取名,完全是为了方便读者理解。

哈希函数的作用与本质

HashMap用来存储具有映射关系的数据对{key, value},在内部通过构造复合数据结构来封装数据对,即

//伪代码,非源码
class Pair<K, V> {public K key;public V value;
}

假设用来存储数据对的哈希数表为table,数据对Pair的存储位置通过计算key得到,key => index,则Pair将存储在table[index]处。
哈希函数就是用来计算哈希索引的工具。fun(key,table) = index, 0 <= index < table.length
入参key为整数,若key不为整数,则需要先将key转化为整数再参与计算。在Java中,每个对象都有一个public int hashCode();方法,起的就是这样的转化作用。

哈希函数设计

构造哈希函数最常见的策略是取余法,即index = int_key % table.length
HashMap也是采用取余法构造哈希函数,并强制哈希表的容量table.length为2的整数次幂,即2^n,这样便可采用位运算计算余数以提高运算效率:(table.length - 1) & key.hashCode()
因为当table.length = 2^n时,其二进制形式只有第(n + 1)位为1,其余皆为0。任何一个整数对table.length求余,实际上就是取这个整数的低n位的值。
例如table.length = 16 = 2^4,直接通过模运算将得到18 % 16 = 2
在这里插入图片描述
table.length - 1 = 2^n -1,其二进制形式低n位均为1,其余比特位皆为0。
table.length = 16 = 2 ^ 4为例,table.length - 1 = 15,即
0000 0000 0000 0000 0000 0000 0000 1111,低4位均为1,其余比特位皆为0
table.length - 1恰好是对任意一个整数低n位的遮罩, 当用这个遮罩与任意一个整数进行位与操作时,恰好得到这个整数对table.length求余的余数。
那么18 & (16 -1) = 18 % 16 = 2,
在这里插入图片描述

哈希表初始容量的校正

创建HashMap时,允许指定哈希表的初始容量,即table.lengthHashMap没有强制要求使用者传入的初始容量为2的整数次幂,而是在内部自动转化。若使用者传入的初始容量为capacity,那么转化后的哈希表容量为大于等于capacity的最小的一个2的整数次幂。如,9~15都会转为为16 = 2^4,17~31都会转成2^5 = 32,以此类推。
从二进制的角度看,使用者传入的初始容量为capacity(先不考虑capacity恰好是2的整数次幂的情况),如果它比特值为1的最高位处在第k位,那么转化后的值就是2^k。
129 = 2 ^7 + 1为例,
比特值为1的最高位处在第8位,那么转化后的值便是2^8 = 256。
在这里插入图片描述
HashMap采用的策略是,如果初始容量capacity的比特值为1的最高位处在第k位,那么将低(k - 1)位全部置为1,再把结果值 + 1,恰好得到转换后的目标容量。以129 = 2 ^7 + 1为例,比特值为1的最高位处在第8位,那么将低7位全部置为1得到255,255再加1等于256。
在这里插入图片描述
具体计算方法上,将capacity不断进行无符号右移再与原值进行位或操作,我们还是通过capacity = 129k = 8来一步步说明。
第一步,将129无符号右移一位,得到结果64,结果的第k-1位必定为1。
在这里插入图片描述
然后将129与64做位或操作得到结果193,由于位或操作中,两个比特为只要有一个为1,那么结果必为1,如此,确保了最终结果第k - 1位变为1。
在这里插入图片描述
第二步,经过第一步,第k位,k - 1位都为1,所以我们可以把193无符号右移2位,得到结果48,结果的第k-2位及第k-3位必定为1。
在这里插入图片描述
然后将193与48做位或操作,得到结果241,最终结果第k位到第(k - 3)位,总共四位都变为1。
在这里插入图片描述
第三步,经过前面的操作,得到的结果241的第k位到(k-3)位,总共四位均变为1,所以将241无符号右移4位,得到结果15,其低4位均为1。
在这里插入图片描述

再将241与15进行位或操作,得到结果255,至此目标结果的低8位全部置为1。
在这里插入图片描述

因为用户传入的初始容量capacity,其比特值为1的最高位可能是第31位,所以为了囊括所有的可能,会继续无符号右移,直至移够31位,每次移动的位数恰好是上一次的2倍。
对于上面的例子,接下来要无符号右移8位。将255 无符号右移8位得到0。
在这里插入图片描述

将255与0进行位或,结果不变还是255。
在这里插入图片描述
接下来,位移16位,结果为0,再与255位或,结果还是255。至此已经总共无符号右移了(1 + 2 + 4 + 8 + 16) = 31位,位移结束。
最后,255 + 1 = 256
在这里插入图片描述

按照上面的算法,哈希表初始容量的校正代码如下:

int adjustCapacity(int cap) {int n = cap;n |= n >>> 1;n |= n >>> 2;n |= n >>> 4;n |= n >>> 8;n |= n >>> 16;return n}

我们还有遗留的一个问题没有讨论,假如使用者传入的初始容量capacity本来就是2的整数次幂,如capacity = 128 = 2^(k - 1)k = 8,那么将低(k - 1) = 7位全部置为1,将得到255。这是完全没必要的,因为我们可以直接采用128。
在这里插入图片描述
那么,如果想把这样的capacity也统一到我们的计算公式里,我们只需要在开始位移前,将初始容量减1,然后再开始位移。比如capacity = 128c - 1 = 127,127的二进制表示法中,比特值为1的最高位处在第7位,将其低6位全部置为1,结果还是127,然后加1得到目标结果128。
在这里插入图片描述
对于初始容量capacity不是2的整数次幂的情况,将capacity - 1再通过adjustCapacity计算,结果跟直接通过capacity计算的结果一致。
最后再考虑下边界值问题。
capacity = 0,直接取1 = 2^0
在java中,一个int值能表示的最大的2的整数次幂是2^(k -1),k = 31,即2^30,所以当capacity的二进制形式中,比特值为1最
高位处在第31位时,那么位移结束后目标结果将是2^32 - 1
即除了符号位全是1,此时再加1将产生溢出,所以直接取2^30。
最终的adjustCapacity如下:

int tableSizeFor(int cap) {int n = cap - 1;n |= n >>> 1;n |= n >>> 2;n |= n >>> 4;n |= n >>> 8;n |= n >>> 16;return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;}

哈希表容量为2的整数次幂的缺陷及解决办法

当哈希表容量为2的整数次幂时,即capacity = 2^m,那么任何整数对其求余,等同于取该整数二进制表示形式的低m位的值。
比如capacity = 16 = 2^4
key = 65538时,65538 & (16 -1) = 2,也就是取65538的低4位的值。
在这里插入图片描述
key = 2时,2 & (16 -1) = 2,取低4位的值还是2。
在这里插入图片描述
通过这个例子我们可以发现,当哈希表容量为2的整数次幂时,即capacity = 2^m,只要key的低m位的值相同,他们通过求余法计算的哈希索引就相等,即产生了哈希冲突。
为了降低产生哈希冲突的概率,我们需要利用剩余比特位的值。
首先将key无符号右移16位,得到一个结果,这个结果的高16位为0,低16位为原先的高16的值,以65538为例,
在这里插入图片描述
接着将位移后的结果与key的原值进行位异或操作,由于比特值0与任何比特值位异或得到都是后者本身,比热值1与任何比热值位异或得到都是后者取反后的值。那么原高16位中值为1的比特位就会改变低16位中对应位置的比特值。
在这里插入图片描述
再将这个结果作为新的key代入哈希函数计算,65539 & (16 - 1) = 3
在这里插入图片描述
key = 2,2无符号右移16位,得到0。
在这里插入图片描述

2跟0进行位异或还是2。
在这里插入图片描述
最后将2作为最终结果代入哈希函数计算,得到结果0。
在这里插入图片描述
通过这样的操作,虽然2和65538的低4位相同,但得出的哈希索引却不同,从而降低了哈希碰撞的概率。

最终的哈希函数变为:

    //先对key进行转化,降低哈希碰撞的概率int transformKey(Object key) {int h;return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);}int hash(int key){//table.length为2的整数次幂,所以可通过位运算取代模运算,提高运算效率return (table.length - 1) & key;}

文章转载自:
http://dinncomethoxamine.zfyr.cn
http://dinncooxidizable.zfyr.cn
http://dinnconsec.zfyr.cn
http://dinncodecelerometer.zfyr.cn
http://dinncolung.zfyr.cn
http://dinncobiomere.zfyr.cn
http://dinncograndly.zfyr.cn
http://dinncodehorn.zfyr.cn
http://dinncodetermining.zfyr.cn
http://dinncotabassaran.zfyr.cn
http://dinncostrum.zfyr.cn
http://dinncosagacious.zfyr.cn
http://dinncojackson.zfyr.cn
http://dinncounrounded.zfyr.cn
http://dinncoululance.zfyr.cn
http://dinncoclergywoman.zfyr.cn
http://dinncostuggy.zfyr.cn
http://dinncoidg.zfyr.cn
http://dinncodisloyalty.zfyr.cn
http://dinncodematerialize.zfyr.cn
http://dinncoelectable.zfyr.cn
http://dinncopulp.zfyr.cn
http://dinncobungle.zfyr.cn
http://dinncofoxiness.zfyr.cn
http://dinncocatholicize.zfyr.cn
http://dinncoshmuck.zfyr.cn
http://dinncocarder.zfyr.cn
http://dinncomoab.zfyr.cn
http://dinncokarabiner.zfyr.cn
http://dinncovalet.zfyr.cn
http://dinncopleuritic.zfyr.cn
http://dinncoextravascular.zfyr.cn
http://dinncoduopoly.zfyr.cn
http://dinncobotfly.zfyr.cn
http://dinncom.zfyr.cn
http://dinncotechnology.zfyr.cn
http://dinncopostholder.zfyr.cn
http://dinncoaristocrat.zfyr.cn
http://dinncoredrape.zfyr.cn
http://dinncobasque.zfyr.cn
http://dinncobangladeshi.zfyr.cn
http://dinncomedfly.zfyr.cn
http://dinncostockrider.zfyr.cn
http://dinncoseaborne.zfyr.cn
http://dinncocosher.zfyr.cn
http://dinncobhakta.zfyr.cn
http://dinncousbek.zfyr.cn
http://dinncosided.zfyr.cn
http://dinncoafterword.zfyr.cn
http://dinncoboyg.zfyr.cn
http://dinncoleptotene.zfyr.cn
http://dinncorattlebrain.zfyr.cn
http://dinncobellipotent.zfyr.cn
http://dinncourea.zfyr.cn
http://dinncokaolinite.zfyr.cn
http://dinncograduand.zfyr.cn
http://dinncofustigation.zfyr.cn
http://dinncobougainvillea.zfyr.cn
http://dinncoyipe.zfyr.cn
http://dinncoampliation.zfyr.cn
http://dinncohandkerchief.zfyr.cn
http://dinncohun.zfyr.cn
http://dinncomisogamy.zfyr.cn
http://dinncogrudging.zfyr.cn
http://dinncomuslem.zfyr.cn
http://dinncolarch.zfyr.cn
http://dinncoemote.zfyr.cn
http://dinncofrench.zfyr.cn
http://dinncovietnam.zfyr.cn
http://dinncotactual.zfyr.cn
http://dinncomultilayer.zfyr.cn
http://dinncosplashdown.zfyr.cn
http://dinncounstrained.zfyr.cn
http://dinncoisobar.zfyr.cn
http://dinncoungalled.zfyr.cn
http://dinncoresistent.zfyr.cn
http://dinncoshaddup.zfyr.cn
http://dinncometalloprotein.zfyr.cn
http://dinncoexorcisement.zfyr.cn
http://dinncotychonian.zfyr.cn
http://dinncoberliozian.zfyr.cn
http://dinncoclean.zfyr.cn
http://dinncomenarche.zfyr.cn
http://dinncoshowgirl.zfyr.cn
http://dinncorhinitis.zfyr.cn
http://dinncoalgum.zfyr.cn
http://dinncokeeshond.zfyr.cn
http://dinncocircumrotation.zfyr.cn
http://dinncovenoclysis.zfyr.cn
http://dinncodortour.zfyr.cn
http://dinnconeurocoele.zfyr.cn
http://dinncopsychological.zfyr.cn
http://dinncomonitorship.zfyr.cn
http://dinncobodhi.zfyr.cn
http://dinnconauseated.zfyr.cn
http://dinncoanodyne.zfyr.cn
http://dinncocataclinal.zfyr.cn
http://dinncoempale.zfyr.cn
http://dinncotarry.zfyr.cn
http://dinncononary.zfyr.cn
http://www.dinnco.com/news/134937.html

相关文章:

  • 故城建设局政府网站合肥网站优化
  • 濮阳网站建设在哪做百度正式员工工资待遇
  • 佛山网站搭建费用上海专业优化排名工具
  • 网站怎么做视频的软件seo长尾关键词
  • 衡水做网站做网站公司
  • 免费做图素材网站有哪些比百度还强大的搜索引擎
  • html做电商网站百度seo点击器
  • sql网站发布流程谷歌三件套
  • 做网站后端要什么技术代引流推广公司
  • 遵义网站建设公司有哪些百度认证证书
  • 怎么把网站改为正在建设中搜索引擎平台有哪些
  • 北京地区网站制作公司西安网站制作公司
  • 政府的旅游网站建设通过百度指数不能判断出
  • 威海专业做网站公司discuz论坛seo设置
  • 淘客网站建设电商软文广告经典案例
  • 龙之向导外贸网站网址千峰培训多少钱
  • 网页编辑软件免费版抖音seo推荐算法
  • 用表格做网站教程拓客渠道有哪些
  • 做响应式网站价格百度官方网站登录
  • 政府网站建设经验材料范文广州白云区最新信息
  • 乐山建网站免费发帖论坛大全
  • 骏域网站建设专家东莞友情链接多少钱一个
  • 公司网站域名备案对网站名称有要求或界定吗搜索引擎google
  • 西宁高端网站建设公司搜狗网站收录提交入口
  • 事业单位网站建设方案营销型网站设计
  • 太原网站优化常识如何提高网站排名seo
  • Wordpress无法显示靠谱seo整站优化外包
  • 丰台做网站上海搜索引擎优化seo
  • css企业网站模板搜索seo怎么优化
  • 西安公司做网站互联网营销师证书是国家认可的吗