最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java中對HashMap的put過程解讀

 更新時間:2023年03月22日 16:05:14   作者:新時代的農(nóng)民工  
這篇文章主要介紹了java中對HashMap的put過程解讀,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

HashMap解析put的過程

首先,用代碼運(yùn)行下,來體會下:

代碼實(shí)現(xiàn):

@Test
	public void test1() {
		//創(chuàng)建了一個HashMap
		Map<String,Object>map = new HashMap<>();

		//使用put方法保存數(shù)據(jù)
		map.put("age", 12);
		map.put("name", "gaga");
		
		System.out.println(map);
		}

運(yùn)行結(jié)果:

首先經(jīng)過了hash之后的key,是一個整型的hashcode,其次是我們傳入的key和value。

首先一進(jìn)入putVal就會聲明存放數(shù)據(jù)的table,如果這個HashMap是首次設(shè)置值,就會被初始化一個默認(rèn)size的table,且所有元素的初始值都是NULL。

默認(rèn)值為啥是16

通過源碼解析,在注釋中會得到“The default initial capacity - MUST be a power of two.”意思是:默認(rèn)初始容量-必須是2的冪。

自動擴(kuò)容

除了size,初始化的時候還會設(shè)定一個閾值,值為12,newThr = 12,這里需要提到一個概念負(fù)載因子,HashMap的實(shí)現(xiàn)里默認(rèn)給的是0.75。

負(fù)載因子是用來干嘛的呢?當(dāng)我們不停的往map里存數(shù)據(jù)的時候,總會存滿,當(dāng)元素快存滿的時候,我們就需要擴(kuò)大map的容量,來容納更多的元素,這就需要一個自動擴(kuò)容的機(jī)制了。

在當(dāng)數(shù)據(jù)量大于超過設(shè)定的閾值的時候(容量*負(fù)載因子),自動對map進(jìn)行擴(kuò)容,以存放更多的數(shù)據(jù)。

自動擴(kuò)容做了什么事情呢?

  • 1、創(chuàng)建新的數(shù)組,大小是原來數(shù)組的一倍。
  • 2、將元素rehash到新的數(shù)組

為什么要rehash呢?上面我們提到過了,當(dāng)元素被放進(jìn)map時,確認(rèn)下標(biāo)的方法是table的長度-1和hash值做與運(yùn)算,現(xiàn)在table的長度發(fā)生了變化,那么自然而然,元素獲取下標(biāo)的運(yùn)算結(jié)果也就跟之前的不一樣了, 所以需要將老的map中的元素再按照新的table長度rehash到擴(kuò)容后的table中。

put的過程

了解了底層數(shù)據(jù)結(jié)構(gòu)和自動擴(kuò)容機(jī)制,接下來我們來看一下put過程中究竟發(fā)生了什么。

我們上面說過了,會通過數(shù)組的長度-1和hash值與運(yùn)算得到一個數(shù)組下標(biāo)。

如果該位置沒有元素,那么就很簡單,直接新建一個節(jié)點(diǎn)即可然后放置在數(shù)據(jù)的具體位置即可。

tab[i] = this.newNode(hash, key, value, (HashMap.Node)null);

但是如果該下標(biāo)已經(jīng)有元素了,這種情況HashMap是怎么處理的呢?這也要看情況。

如果是跟當(dāng)前槽位相同的key,就直接覆蓋。這就是我們修改某個key的值會發(fā)生的情況。

那HashMap怎么來判斷是不是同一個key呢?

就像下面這樣。p就是當(dāng)前槽位上已經(jīng)有的元素,如果新、老元素的key的hashCode和值都相同且key不為空,那么就能證明這兩個key是相同的,那么此時只需要覆蓋即可。

p.hash == hash && ((k = p.key) == key || (key != null && key.equals(k)))

而如果p是TreeNode的實(shí)例,那么就代表當(dāng)前槽位已經(jīng)是一個紅黑樹了,此時只需要往這個樹里putTreeVal即可。

至于為什么是紅黑樹,哪兒來的紅黑樹,下面馬上就要講到了。

最后一種情況就是,既不是已經(jīng)存在的元素也不是TreeNode的實(shí)例,也不是紅黑樹。這種情況下,它就是一個普通的Node。

你可以理解為鏈表,如果hash沖突了,就把這個Node放到該位置的鏈表末尾。

當(dāng)該位置的鏈表中的元素超過了TREEIFY_THRESHOLD所設(shè)置的數(shù)量時,就會觸發(fā)樹化,將其轉(zhuǎn)化為紅黑樹。Java8里給的默認(rèn)值是8。

為啥要轉(zhuǎn)化成紅黑樹?

首先我們要知道為什么要樹化。

當(dāng)大量的數(shù)據(jù)放入Map中,Hash沖突會越來越多,某些位置就會出現(xiàn)一個很長的鏈表的情況。

這種情況下,查詢時間復(fù)雜度是O(n) ,刪除的時間復(fù)雜度也是O(n),查詢、刪除的效率會大大降低。

而同樣的數(shù)據(jù)情況下,平衡二叉樹的時間復(fù)雜度都是O(logn)。

總結(jié)

以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 關(guān)于SpringBoot中Ajax跨域以及Cookie無法獲取丟失問題

    關(guān)于SpringBoot中Ajax跨域以及Cookie無法獲取丟失問題

    這篇文章主要介紹了關(guān)于SpringBoot中Ajax跨域以及Cookie無法獲取丟失問題,本文具有參考意義,遇到相同或者類似問題的小伙伴希望可以從中找到靈感
    2023-03-03
  • 完美解決idea光標(biāo)變成了insert光標(biāo)狀態(tài)的問題

    完美解決idea光標(biāo)變成了insert光標(biāo)狀態(tài)的問題

    這篇文章主要介紹了完美解決idea光標(biāo)變成了insert光標(biāo)狀態(tài)的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02
  • java字符串相似度算法

    java字符串相似度算法

    這篇文章主要介紹了java字符串相似度算法,是Java實(shí)現(xiàn)比較典型的算法,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-02-02
  • Mybatis一對多與多對一查詢處理詳解

    Mybatis一對多與多對一查詢處理詳解

    這篇文章主要給大家介紹了關(guān)于Mybatis一對多與多對一查詢處理的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • springboot使用redis的詳細(xì)步驟

    springboot使用redis的詳細(xì)步驟

    SpringBoot對常用的數(shù)據(jù)庫支持外,對NoSQL?數(shù)據(jù)庫也進(jìn)行了封裝自動化,下面這篇文章主要給大家介紹了關(guān)于springboot使用redis的詳細(xì)步驟,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-06-06
  • java實(shí)現(xiàn)數(shù)據(jù)庫主鍵生成示例

    java實(shí)現(xiàn)數(shù)據(jù)庫主鍵生成示例

    這篇文章主要介紹了java實(shí)現(xiàn)數(shù)據(jù)庫主鍵生成示例,需要的朋友可以參考下
    2014-03-03
  • Java?ASM使用logback日志級別動態(tài)切換方案展示

    Java?ASM使用logback日志級別動態(tài)切換方案展示

    這篇文章主要介紹了Java?ASM使用logback日志級別動態(tài)切換方案展示,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪
    2022-04-04
  • Spring AOP注解失效的坑及JDK動態(tài)代理

    Spring AOP注解失效的坑及JDK動態(tài)代理

    這篇文章主要介紹了Spring AOP注解失效的坑及JDK動態(tài)代理,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-03-03
  • Mybatis?Web中的數(shù)據(jù)庫操作方法舉例詳解

    Mybatis?Web中的數(shù)據(jù)庫操作方法舉例詳解

    Mybatis是一款優(yōu)秀的持久化框架,用于簡化JDBC的開發(fā),下面這篇文章主要給大家介紹了關(guān)于Mybatis?Web中數(shù)據(jù)庫操作方法的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-09-09
  • java date類與string類實(shí)例代碼分享

    java date類與string類實(shí)例代碼分享

    這篇文章主要介紹了java date類與string類實(shí)例代碼分享,具有一定借鑒價值,需要的朋友可以參考下
    2018-01-01

最新評論

濮阳县| 金平| 雅安市| 武定县| 衡阳市| 凤凰县| 吉水县| 昭苏县| 抚州市| 盐山县| 南丹县| 富川| 贡觉县| 财经| 靖宇县| 正宁县| 姚安县| 平利县| 余江县| 洛浦县| 扶沟县| 周至县| 彰武县| 天台县| 阿拉善左旗| 乌恰县| 德令哈市| 柏乡县| 邵东县| 龙江县| 清徐县| 乌兰浩特市| 洮南市| 鹤庆县| 阜南县| 进贤县| 寻乌县| 申扎县| 子长县| 德州市| 镇赉县|