国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

HashMap就是這么簡單【源碼剖析】

entner / 859人閱讀

前言
聲明,本文用得是jdk1.8

前面已經(jīng)講了Collection的總覽和剖析List集合以及散列表、Map集合、紅黑樹的基礎(chǔ)了:

Collection總覽

List集合就這么簡單【源碼剖析】

Map集合、散列表、紅黑樹介紹

本篇主要講解HashMap,以及涉及到一些與hashtable的比較~

看這篇文章之前最好是有點數(shù)據(jù)結(jié)構(gòu)的基礎(chǔ):

Java實現(xiàn)單向鏈表

棧和隊列就是這么簡單

二叉樹就這么簡單

當(dāng)然了,如果講得有錯的地方還請大家多多包涵并不吝在評論去指正~

一、HashMap剖析

首先看看HashMap的頂部注釋說了些什么:

再來看看HashMap的類繼承圖:

下面我們來看一下HashMap的屬性:

成員屬性有這么幾個:

再來看一下hashMap的一個內(nèi)部類Node:

我們知道Hash的底層是散列表,而在Java中散列表的實現(xiàn)是通過數(shù)組+鏈表的~

再來簡單看看put方法就可以印證我們的說法了:數(shù)組+鏈表-->散列表

我們可以簡單總結(jié)出HashMap:

無序,允許為null,非同步

底層由散列表(哈希表)實現(xiàn)

初始容量和裝載因子對HashMap影響挺大的,設(shè)置小了不好,設(shè)置大了也不好

1.1HashMap構(gòu)造方法

HashMap的構(gòu)造方法有4個:

在上面的構(gòu)造方法最后一行,我們會發(fā)現(xiàn)調(diào)用了tableSizeFor(),我們進去看看:

這是位運算算法,具體流程可參考:

https://www.cnblogs.com/loading4/p/6239441.html

https://blog.csdn.net/fan2012huan/article/details/51097331

看完上面可能會感到奇怪的是:為啥是將2的整數(shù)冪的數(shù)賦給threshold

threshold這個成員變量是閾值,決定了是否要將散列表再散列。它的值應(yīng)該是:capacity * load factor才對的。

其實這里僅僅是一個初始化,當(dāng)創(chuàng)建哈希表的時候,它會重新賦值的:

至于別的構(gòu)造方法都差不多,這里我就不細講了:

1.2put方法

put方法可以說是HashMap的核心,我們來看看:

我們來看看它是怎么計算哈希值的:

為什么要這樣干呢??我們一般來說直接將key作為哈希值不就好了嗎,做異或運算是干嘛用的??

我們看下來:

我們是根據(jù)key的哈希值來保存在散列表中的,我們表默認的初始容量是16,要放到散列表中,就是0-15的位置上。也就是tab[i = (n - 1) & hash]??梢园l(fā)現(xiàn)的是:在做&運算的時候,僅僅是后4位有效~那如果我們key的哈希值高位變化很大,低位變化很小。直接拿過去做&運算,這就會導(dǎo)致計算出來的Hash值相同的很多。

而設(shè)計者將key的哈希值的高位也做了運算(與高16位做異或運算,使得在做&運算時,此時的低位實際上是高位與低位的結(jié)合),這就增加了隨機性,減少了碰撞沖突的可能性!

下面我們再來看看流程是怎么樣的:

新值覆蓋舊值,返回舊值測試:

接下來我們看看resize()方法,在初始化的時候要調(diào)用這個方法,當(dāng)散列表元素大于capacity * load factor的時候也是調(diào)用resize()

1.3get方法

接下來我們看看getNode()是怎么實現(xiàn)的:

1.4remove方法

再來看看removeNode()的實現(xiàn):

二、HashMap與Hashtable對比
從存儲結(jié)構(gòu)和實現(xiàn)來講基本上都是相同的。它和HashMap的最大的不同是它是線程安全的,另外它不允許key和value為null。Hashtable是個過時的集合類,不建議在新代碼中使用,不需要線程安全的場合可以用HashMap替換,需要線程安全的場合可以用ConcurrentHashMap替換

Hashtable具體閱讀源碼可參考:

https://blog.csdn.net/panweiwei1994/article/details/77427010

https://blog.csdn.net/panweiwei1994/article/details/77428710

四、總結(jié)

在JDK8中HashMap的底層是:數(shù)組+鏈表(散列表)+紅黑樹

在散列表中有裝載因子這么一個屬性,當(dāng)裝載因子*初始容量小于散列表元素時,該散列表會再散列,擴容2倍!

裝載因子的默認值是0.75,無論是初始大了還是初始小了對我們HashMap的性能都不好

裝載因子初始值大了,可以減少散列表再散列(擴容的次數(shù)),但同時會導(dǎo)致散列沖突的可能性變大(散列沖突也是耗性能的一個操作,要得操作鏈表(紅黑樹)!

裝載因子初始值小了,可以減小散列沖突的可能性,但同時擴容的次數(shù)可能就會變多!

初始容量的默認值是16,它也一樣,無論初始大了還是小了,對我們的HashMap都是有影響的:

初始容量過大,那么遍歷時我們的速度就會受影響~

初始容量過小,散列表再散列(擴容的次數(shù))可能就變得多,擴容也是一件非常耗費性能的一件事~

從源碼上我們可以發(fā)現(xiàn):HashMap并不是直接拿key的哈希值來用的,它會將key的哈希值的高16位進行異或操作,使得我們將元素放入哈希表的時候增加了一定的隨機性。

還要值得注意的是:并不是桶子上有8位元素的時候它就能變成紅黑樹,它得同時滿足我們的散列表容量大于64才行的~

明天要是無意外的話,可能會寫TreeMap,敬請期待哦~~~~

文章的目錄導(dǎo)航:https://zhongfucheng.bitcron.com/post/shou-ji/gong-zhong-hao-wen-zhang-zheng-li

如果文章有錯的地方歡迎指正,大家互相交流。習(xí)慣在微信看技術(shù)文章,想要獲取更多的Java資源的同學(xué),可以關(guān)注微信公眾號:Java3y。為了大家方便,剛新建了一下qq群:742919422,大家也可以去交流交流。
謝謝支持了!希望能多介紹給其他有需要的朋友

參考資料:

《Core Java》

https://blog.csdn.net/panweiwei1994/article/details/76555359

https://zhuanlan.zhihu.com/p/28216267

https://blog.csdn.net/fan2012huan/article/details/51097331

https://www.cnblogs.com/chinajava/p/5808416.html

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/69009.html

相關(guān)文章

  • 3分鐘搞掂Set集合

    摘要:下面總結(jié)一下集合常用的三個子類吧無序,允許為,底層是散列表紅黑樹,非線程同步有序,不允許為,底層是紅黑樹非線程同步迭代有序,允許為,底層是雙向鏈表,非線程同步從結(jié)論而言我們就可以根據(jù)自己的實際情況來使用了。 前言 聲明,本文用的是jdk1.8 前面章節(jié)回顧: Collection總覽 List集合就這么簡單【源碼剖析】 Map集合、散列表、紅黑樹介紹 HashMap就是這么簡單【源碼...

    widuu 評論0 收藏0
  • LinkedHashMap這么簡單源碼剖析

    摘要:習(xí)慣在微信看技術(shù)文章,想要獲取更多的資源的同學(xué),可以關(guān)注微信公眾號。為了大家方便,剛新建了一下群,大家也可以去交流交流。謝謝支持了希望能多介紹給其他有需要的朋友 前言 聲明,本文用得是jdk1.8 前面已經(jīng)講了Collection的總覽和剖析List集合以及散列表、Map集合、紅黑樹還有HashMap基礎(chǔ)了: Collection總覽 List集合就這么簡單【源碼剖析】 Map集合、...

    avwu 評論0 收藏0
  • ConcurrentHashMap基于JDK1.8源碼剖析

    摘要:下面我來簡單總結(jié)一下的核心要點底層結(jié)構(gòu)是散列表數(shù)組鏈表紅黑樹,這一點和是一樣的。是將所有的方法進行同步,效率低下。而作為一個高并發(fā)的容器,它是通過部分鎖定算法來進行實現(xiàn)線程安全的。 前言 聲明,本文用的是jdk1.8 前面章節(jié)回顧: Collection總覽 List集合就這么簡單【源碼剖析】 Map集合、散列表、紅黑樹介紹 HashMap就是這么簡單【源碼剖析】 LinkedHas...

    sanyang 評論0 收藏0
  • Java集合總結(jié)【面試題+腦圖】,將知識點一網(wǎng)打盡!

    摘要:而在集合中,值僅僅是一個對象罷了該對象對本身而言是無用的。將這篇文章作為集合的總結(jié)篇,但覺得沒什么好寫就回答一些面試題去了,找了一會面試題又覺得不夠系統(tǒng)。 前言 聲明,本文用的是jdk1.8 花了一個星期,把Java容器核心的知識過了一遍,感覺集合已經(jīng)無所畏懼了??!(哈哈哈....),現(xiàn)在來總結(jié)一下吧~~ 回顧目錄: Collection總覽 List集合就這么簡單【源碼剖析】 Ma...

    yearsj 評論0 收藏0
  • TreeMap就這么簡單源碼剖析

    摘要:在這種情況下,是以其為根的樹的最后一個結(jié)點。來源二總結(jié)底層是紅黑樹,能夠?qū)崿F(xiàn)該集合有序如果在構(gòu)造方法中傳遞了對象,那么就會以對象的方法進行比較。 前言 聲明,本文用得是jdk1.8 前面章節(jié)回顧: Collection總覽 List集合就這么簡單【源碼剖析】 Map集合、散列表、紅黑樹介紹 HashMap就是這么簡單【源碼剖析】 LinkedHashMap就這么簡單【源碼剖析】 本...

    ormsf 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<