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

Java中的LinkedHashMap源碼分析

 更新時(shí)間:2023年12月15日 08:42:29   作者:愛喝咖啡的程序員  
這篇文章主要介紹了Java中的LinkedHashMap源碼分析,LinkedHashMap是HashMap的子類,所以基本的操作與hashmap類似,不過呢,在插入、刪除、替換key-value對(duì)的時(shí)候,需要的朋友可以參考下

一. 基本原理和優(yōu)缺點(diǎn)

LinkedHashMap能記錄你插入元素的順序,在遍歷時(shí),能按照插入的順序給你遍歷出來(lái)。

LinkedHashMap是HashMap的子類,所以基本的操作與hashmap類似。不過呢,在插入、刪除、替換key-value對(duì)的時(shí)候,LinkedHashMap會(huì)維護(hù)一個(gè)鏈表結(jié)構(gòu),專門用來(lái)記錄key-value對(duì)的順序。當(dāng)我們遍歷LinkedHashMap時(shí),就能按照順序把key-value來(lái)遍歷出來(lái)。

所以啊,別看LinkedHashMap的名字中帶有Linked,其實(shí)它的底層仍然是數(shù)組實(shí)現(xiàn)的。

當(dāng)刪除元素時(shí),它會(huì)在雙向鏈表的尾部刪除節(jié)點(diǎn),當(dāng)查詢?cè)貢r(shí),實(shí)際上是在迭代雙向鏈表,從頭節(jié)點(diǎn)開始迭代。用于維護(hù)雙向鏈表的順序。

這里面有一個(gè)非常核心的參數(shù): accessOrder。

二. 源碼分析

2.1 put(K key, V value) 初次插入

絕大部分代碼邏輯與hashmap完全一樣,只不過,LinkedHashMap自己重寫了newNode()方法。

Node<K,V> newNode(int hash, K key, V value, Node<K,V> e) {
	LinkedHashMap.Entry<K,V> p = new LinkedHashMap.Entry<K,V>(hash, key, value, e);
	linkNodeLast(p);
	return p;
}

將節(jié)點(diǎn)封裝成了LinkedHashMap.Entry對(duì)象,然后使用linkNodeLast()掛載節(jié)點(diǎn)。

private void linkNodeLast(LinkedHashMap.Entry<K,V> p) {
	LinkedHashMap.Entry<K,V> last = tail;
	tail = p;
	if (last == null)
		head = p;
	else {
		p.before = last;
		last.after = p;
	}
}

這里可以看到,LinkedHashMap內(nèi)部維護(hù)了兩個(gè)指針head和tail,分別指向順序鏈表的頭結(jié)點(diǎn)和尾結(jié)點(diǎn)。

每當(dāng)我們向LinkedHashMap內(nèi)新增一個(gè)key-value,就會(huì)在順序鏈表的末尾掛載一個(gè)順序節(jié)點(diǎn)。這個(gè)掛載的過程其實(shí)就是對(duì)雙向鏈表新增一個(gè)節(jié)點(diǎn)。

2.2 put(K key, V value) 覆蓋已經(jīng)存在的key

如果LinkedHashMap中已經(jīng)插入了key1-value1,此時(shí)我們插入key1-value2,會(huì)產(chǎn)生什么后果呢?

答案是,key1在LinkedHashMap內(nèi)的插入順序保持不變,但是value被覆蓋。

關(guān)于覆蓋的操作,由于我們熟悉HashMap的源碼,所以立刻可以鎖定到hashmap的putVal()內(nèi)如下代碼塊:

if (e != null) { // existing mapping for key
	V oldValue = e.value;
	if (!onlyIfAbsent || oldValue == null)
		e.value = value;
	afterNodeAccess(e);
	return oldValue;
}

如果在插入之前,能找到這個(gè)key對(duì)應(yīng)的節(jié)點(diǎn),那么就用新的value覆蓋這個(gè)節(jié)點(diǎn)內(nèi)的舊value,接著執(zhí)行afterNodeAccess(e)。

注意,LinkedHashMap重寫了afterNodeAccess(e)。

void afterNodeAccess(Node<K,V> e) { // move node to last
	LinkedHashMap.Entry<K,V> last;
	if (accessOrder && (last = tail) != e) {
		LinkedHashMap.Entry<K,V> p =
			(LinkedHashMap.Entry<K,V>)e, b = p.before, a = p.after;
		p.after = null;
		if (b == null)
			head = a;
		else
			b.after = a;
		if (a != null)
			a.before = b;
		else
			last = b;
		if (last == null)
			head = p;
		else {
			p.before = last;
			last.after = p;
		}
		tail = p;
		++modCount;
	}
}

LinkedHashMap有一個(gè)非常重要的參數(shù),accessOrder ,它可以通過入?yún)ⅲ?jīng)過構(gòu)造函數(shù)傳入LinkedHashMap。accessOrder默認(rèn)等于false,這就意味著,你覆蓋或者查詢這個(gè)key,都不會(huì)改變key在鏈表里的順序。當(dāng)它等于true時(shí),就截然相反了,每當(dāng)你覆蓋或者查詢這個(gè)key,LinkedHashMap就會(huì)把這個(gè)key挪動(dòng)到順序鏈表的末尾。

2.3 remove

大部分的邏輯仍然走的是hashmap的removeNode(),只不過LinkedHashMap重寫了afterNodeRemoval( )。

void afterNodeRemoval(Node<K,V> e) { // unlink
	LinkedHashMap.Entry<K,V> p =
		(LinkedHashMap.Entry<K,V>)e, b = p.before, a = p.after;
	p.before = p.after = null;
	if (b == null)
		head = a;
	else
		b.after = a;
	if (a == null)
		tail = b;
	else
		a.before = b;
}

到此這篇關(guān)于Java中的LinkedHashMap源碼分析的文章就介紹到這了,更多相關(guān)LinkedHashMap源碼內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java實(shí)現(xiàn)注冊(cè)登錄系統(tǒng)

    java實(shí)現(xiàn)注冊(cè)登錄系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)注冊(cè)登錄系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • Java?詳細(xì)分析四個(gè)經(jīng)典鏈表面試題

    Java?詳細(xì)分析四個(gè)經(jīng)典鏈表面試題

    兄弟們,編程,當(dāng)我們學(xué)習(xí)完數(shù)據(jù)結(jié)構(gòu)的時(shí)候,你就會(huì)有一種豁然開朗的感覺。算是真正的入了編程的門,所以打好數(shù)據(jù)結(jié)構(gòu)的基礎(chǔ)是特別特別重要的
    2022-03-03
  • java Thread 多線程

    java Thread 多線程

    本篇文章小編為大家介紹,java Thread 多線程。需要的朋友參考下
    2013-04-04
  • Spring Boot整合Swagger測(cè)試api構(gòu)建全紀(jì)錄

    Spring Boot整合Swagger測(cè)試api構(gòu)建全紀(jì)錄

    這篇文章主要給大家介紹了關(guān)于Spring Boot整合Swagger測(cè)試api構(gòu)建的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-01-01
  • Java中生成不重復(fù)隨機(jī)數(shù)的四種方法舉例詳解

    Java中生成不重復(fù)隨機(jī)數(shù)的四種方法舉例詳解

    在Java編程中獲取隨機(jī)數(shù)是常見的需求,這篇文章主要介紹了Java中生成不重復(fù)隨機(jī)數(shù)的四種方法,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2025-04-04
  • 優(yōu)雅地在Java 8中處理異常的方法詳解

    優(yōu)雅地在Java 8中處理異常的方法詳解

    異常處理是我們?cè)谌粘i_發(fā)中經(jīng)常會(huì)遇到的一種需求,下面這篇文章主要給大家介紹了關(guān)于如何優(yōu)雅地在Java 8中處理異常的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們來(lái)一起看看吧
    2019-01-01
  • java中歸并排序和Master公式詳解

    java中歸并排序和Master公式詳解

    大家好,本篇文章主要講的是java中歸并排序和Master公式詳解,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽
    2022-01-01
  • 深入分析JAVA Synchronized關(guān)鍵字

    深入分析JAVA Synchronized關(guān)鍵字

    這篇文章主要介紹了析JAVA Synchronized關(guān)鍵字的相關(guān)知識(shí),文中代碼非常詳細(xì),幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-06-06
  • 詳解spring cloud如何使用spring-test進(jìn)行單元測(cè)試

    詳解spring cloud如何使用spring-test進(jìn)行單元測(cè)試

    這篇文章主要介紹了spring cloud如何使用spring-test進(jìn)行單元測(cè)試,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-11-11
  • Java面試題沖刺第十六天--消息隊(duì)列

    Java面試題沖刺第十六天--消息隊(duì)列

    這篇文章主要為大家分享了最有價(jià)值的三道關(guān)于消息隊(duì)列的面試題,涵蓋內(nèi)容全面,包括數(shù)據(jù)結(jié)構(gòu)和算法相關(guān)的題目、經(jīng)典面試編程題等,感興趣的小伙伴們可以參考一下
    2021-08-08

最新評(píng)論

昭觉县| 松阳县| 龙海市| 积石山| 阜南县| 茶陵县| 黑水县| 方山县| 遂川县| 中牟县| 长乐市| 稷山县| 德钦县| 万山特区| 远安县| 安图县| 土默特右旗| 吴江市| 若羌县| 大足县| 长宁区| 大荔县| 罗江县| 太仓市| 玉林市| 泽州县| 南岸区| 庆元县| 仙桃市| 西和县| 土默特左旗| 平昌县| 乌海市| 海阳市| 若尔盖县| 兖州市| 龙胜| 灵璧县| 丰城市| 通海县| 孟连|