HashMap源碼中的位運(yùn)算符&詳解
引言
最近在讀HashMap源碼的時(shí)候,發(fā)現(xiàn)在很多運(yùn)算符替代常規(guī)運(yùn)算符的現(xiàn)象。比如說(shuō)用hash & (table.length-1) 來(lái)替代取模運(yùn)算hash&(table.length);用if((e.hash & oldCap) == 0)判斷擴(kuò)容后元素的位置等等。
1.取模運(yùn)算符%底層原理
總所周知,位運(yùn)算&直接對(duì)二進(jìn)制進(jìn)行運(yùn)算;而對(duì)于取模運(yùn)算符%:a % b 相當(dāng)于 a - a / b * b,底層實(shí)際上是除法器,究其根源也是由底層的減法和加法共同完成。所以其運(yùn)行效率要遠(yuǎn)遠(yuǎn)小于位運(yùn)算符&。

2.位運(yùn)算符&如何實(shí)現(xiàn)取模功能
我們先來(lái)看兩個(gè)例子
5 & 7 9 & 7
0101----5 1001----9
& &
0111----7 0111----7
= =
0101----5 0001----1
確實(shí),hash & (table.length-1) 來(lái)實(shí)現(xiàn)了運(yùn)算hash&(table.length)從二進(jìn)制的角度來(lái)說(shuō),5%8實(shí)際上是將二進(jìn)制5(0101)向右移動(dòng)3位,而與7(0111)進(jìn)行與運(yùn)算實(shí)際上就是將位數(shù)向右移動(dòng)三位。不過(guò)要注意的是,只有當(dāng)length的長(zhǎng)度為2^n時(shí),結(jié)論才成立。
3.位運(yùn)算符&在if((e.hash & oldCap) == 0)判斷擴(kuò)容后元素的位置
這是出自于JDK1.8中擴(kuò)容函數(shù)resize()的一行代碼,用于判斷在擴(kuò)容后原數(shù)組中的元素是否需要移動(dòng)。舉個(gè)例子:
0001 1010----26 0000 1010----10
& &
0001 0000----16 0001 0000----16
= =
0001 0000----非0 0000 0000-----0
利用hash值和oldCap進(jìn)行與運(yùn)算,很明顯當(dāng)結(jié)果大于0代表hash值大于oldCap時(shí),下標(biāo)位置變?yōu)榕f數(shù)組的下標(biāo)j + oldCap;若結(jié)果等于0代表小于oldCap,則下標(biāo)位置不變。相比于JDK1.7重新計(jì)算每個(gè)元素的哈希值,通過(guò)高位運(yùn)算(e.hash & oldCap)無(wú)疑效率更高。
到此這篇關(guān)于HashMap源碼中的位運(yùn)算符&詳解的文章就介紹到這了,更多相關(guān)HashMap源碼中的位運(yùn)算符&內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringCloud微服務(wù)之Config知識(shí)總結(jié)
今天帶大家學(xué)習(xí)SpringCloud微服務(wù)中的Config的相關(guān)知識(shí),文中有非常詳細(xì)的介紹,對(duì)正在學(xué)習(xí)SpringCloud微服務(wù)的小伙伴們有很好地幫助,需要的朋友可以參考下2021-05-05
SpringBoot如何實(shí)現(xiàn)持久化登錄狀態(tài)獲取
這篇文章主要介紹了SpringBoot 如何實(shí)現(xiàn)持久化登錄狀態(tài)獲取,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11
為什么Spring和IDEA都不推薦使用 @Autowired 注解
本文主要介紹了為什么Spring和IDEA都不推薦使用 @Autowired 注解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-04-04
Java8接口默認(rèn)靜態(tài)方法及重復(fù)注解原理解析
這篇文章主要介紹了Java8接口默認(rèn)靜態(tài)方法及重復(fù)注解原理解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04
解決springcloud中Feign導(dǎo)入依賴為unknow的情況
這篇文章主要介紹了解決springcloud中Feign導(dǎo)入依賴為unknow的情況,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03
javacv-ffmpeg ProcessBuilder批量旋轉(zhuǎn)圖片方式
為了批量處理大量圖片的旋轉(zhuǎn),可以使用javacv-ffmpeg結(jié)合ProcessBuilder,首先在maven配置文件中添加ffmpeg及javacpp依賴,javacpp支持調(diào)用C/C++方法,而ffmpeg基于C語(yǔ)言,使用ProcessBuilder創(chuàng)建進(jìn)程調(diào)用ffmpeg方法2024-09-09
Java 實(shí)戰(zhàn)項(xiàng)目之誠(chéng)途旅游系統(tǒng)的實(shí)現(xiàn)流程
讀萬(wàn)卷書不如行萬(wàn)里路,只學(xué)書上的理論是遠(yuǎn)遠(yuǎn)不夠的,只有在實(shí)戰(zhàn)中才能獲得能力的提升,本篇文章手把手帶你用java+SpringBoot+Vue+maven+Mysql實(shí)現(xiàn)一個(gè)精美的物流管理系統(tǒng),大家可以在過(guò)程中查缺補(bǔ)漏,提升水平2021-11-11
關(guān)于try 和 throw 簡(jiǎn)單使用示例
每過(guò)一段時(shí)間,就總是會(huì)對(duì)try有點(diǎn)生疏,特別寫了個(gè)程序來(lái)測(cè)試以下,有時(shí)候 throw是底層拋出來(lái)的,你不處理,默認(rèn)就throw了2013-08-08

