Java HashMap擴容的時候,為什麼要把Entry鍊錶反轉?這樣做有什麼好處嗎?

時間 2021-06-03 09:36:05

1樓:Absurd

這是 jdk1.7的原始碼

void

resize

(int

newCapacity

)Entry

newTable

=new

Entry

[newCapacity

];transfer

(newTable

,initHashSeedAsNeeded(newCapacity

));table

=newTable

;threshold=(

int)

Math

.min

(newCapacity

*loadFactor

,MAXIMUM_CAPACITY+1

);}/*** 將當前table的Entry轉移到新的table中*/void

transfer

(Entry

newTable

,boolean

rehash

)inti=

indexFor(e

.hash

,newCapacity

);//注意這裡是頭插e.

next

=newTable[i

];newTable[i

]=e;

e=next;}

}}static

intindexFor

(inth,

intlength

)這是來自jdk1.8的原始碼

final

Node

resize

()else

if((

newCap

=oldCap

<<1)

&&oldCap

>=DEFAULT_INITIAL_CAPACITY)newThr

=oldThr

<<1;

// 兩倍

}// 桶陣列為空,第一次分配,結合不同構造器的情況細節稍有不同:

elseif(

oldThr

>0)newCap

=oldThr

;else

//無元素if(

newThr==0

)threshold

=newThr

;@SuppressWarnings

()Node

newTab=(

Node

)new

Node

[newCap

];table

=newTab;if

(oldTab

!=null

)else

}while((e

=next)!=

null

);if

(loTail

!=null)if

(hiTail

!=null)}

}}}return

newTab;}

桶中存在乙個鍊錶,需要將鍊錶重新整理到新錶當中,因為newCap是oldCap的兩倍所以原節點的索引值要麼和原來一樣,要麼就是原(索引+oldCap)和JDK 1.7中實現不同這裡不存在rehash,直接使用原hash 值JDK 1.7中resize過程是在煉表頭插入,這裡是在鍊錶尾插入

golang切片擴容時底層記憶體位址是連續的麼,會不會出現不連續的情況?

從程式角度看,切片不管有沒有擴容,因為底層是陣列,陣列這種型別就是按位址索引訪問的,所以是記憶體連續的,這裡用的是邏輯位址 作業系統組織記憶體的時候是用的虛擬記憶體,用段表和頁表管理物理記憶體分配,實際在物理記憶體這個地方只能保證一頁內連續,跨頁不保證連續 吹雪 即使是不擴容也會有不連續的可能性,g...

C vector 的 push back 擴容機制為什麼不考慮在尾元素後面的空間申請記憶體

流石Lee 按我的理解,考慮到實際執行,等你需要擴容的時候,尾部未必預留了足夠的空間給你,你不知道 當然程式也不知道 執行時,容器的尾元素何時將被誰申請掉。不是不可以考慮,或許這可以作為一種全域性的優化策略,譬如首先避免去申請容器尾元素後面的空間,但是這極難配合 還有其他程序在執行 另一種情況是重新...

家居收納的擴容設計怎麼做?

西安裝修課堂 01進門鞋櫃 鞋櫃每家必不可少,如果有單獨門廳,左右兩邊有空餘都可以定製或者購買成品鞋櫃。矮櫃或者通頂看自己的實際需要 不想要通頂鞋櫃,矮鞋櫃也挺好 如果沒有左右空間,進門直對有玄關背景,也可以做收納櫃兼鞋櫃,矮櫃或者通頂以個人愛好和家裡風格決定 有格調的玄關鞋櫃,值得擁有 鞋櫃作為狹...