今天被問了hashmap的原始碼,雖然之前看過,但是時間一長,而且當時沒有做任何筆記,回答非常的模糊,所以決定回頭再讀一次。
hashmap預設初始化大小為16
tatic final
int default_initial_capacity =
1<<
4;
最大容量為2^30
static
final
int maximum_capacity =
1<<
30;
預設裝載比率為75%,即達到容量的75%就會自動擴容
static
final
float default_load_factor =
0.75f
;
樹形化閾值,眾所周知,為了避免多個雜湊值相等的元素都聚集在同一條鍊錶中,導致查詢效率降低,jdk1.8用紅黑樹代替了鍊錶,但並不是完全代替,當某條鍊錶的節點個數大於8時,會將鍊錶轉為紅黑樹
static
final
int treeify_threshold =
8;
反之,當hashmap擴容是發現某條鍊錶節點個數小於6時,會將紅黑樹還原為鍊錶
static
final
int untreeify_threshold =
6;
當hashmap中的元素容量大於該值64時,上面所講的樹形化才會被執行
static
final
int min_treeify_capacity =
64;
下面記錄一下重點的幾個方法
resize()
//擴容方法
final node
resize()
//如果沒有超過且原有容量擴大一倍不大於最大容量
elseif(
(newcap = oldcap <<1)
< maximum_capacity &&
oldcap >= default_initial_capacity)
newthr = oldthr <<1;
//新的容量為原來的2倍
}else
if(oldthr >0)
// initial capacity was placed in threshold
//如果原容量為0且原map的可裝載元素數大於0,則用原可裝載數作為新map的最大容量
newcap = oldthr;
else
if(newthr ==0)
threshold = newthr;
//這裡初始化乙個新容量的map
@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;
}
上乙個方法resize()中提到了根據某個桶內的元素個數對紅黑樹進行處理,用到的split()方法
final
void
split
(hashmap map, node[
] tab,
int index,
int bit)
else}if
(lohead != null)}if
(hihead != null)
}}
當鍊表元素個數大於閾值時,就會進行桶的樹形化treeifybin()
//將桶內所有的 鍊錶節點 替換成 紅黑樹節點
final
void
treeifybin
(node[
] tab,
int hash)
tl = p;
}while
((e = e.next)
!= null)
;//讓桶的第乙個元素指向新建的紅黑樹頭結點,以後這個桶裡的元素就是紅黑樹而不是鍊錶了if(
(tab[index]
= hd)
!= null)
hd.treeify
(tab);}
} treenode replacementtreenode
(node p, node next)
上乙個方法只是將鍊錶轉化為乙個二叉樹的結構,還沒有但是我們發現,並沒有設定紅黑樹的顏色值,現在得到的只能算是個二叉樹。在 最後呼叫樹形節點 hd.treeify(tab) 方法進行塑造紅黑樹
final
void
treeify
(node[
] tab)
else}}
}moveroottofront
(tab, root)
;}
可以看到,將二叉樹變為紅黑樹時,需要保證有序。這裡有個雙重迴圈,拿樹中的所有節點和當前節點的雜湊值進行對比(如果雜湊值相等,就對比鍵,這裡不用完全有序),然後根據比較結果確定在樹種的位置。 原始碼分析 HashMap原始碼再讀 基於Java8
最近工作不是太忙,準備再讀讀一些原始碼,想來想去,還是先從jdk的原始碼讀起吧,畢竟很久不去讀了,很多東西都生疏了。當然,還是先從炙手可熱的hashmap,每次讀都會有一些收穫。當然,jdk8對hashmap有一次優化 我們首先看到的,應該是它的一些基本引數,這對於我們了解hashmap有一定的作用...
再讀SIFT理論及原始碼
sift特徵點檢測及描述 引言 sift特徵點,尺度不變的特徵變換。其具有尺度不變性 高斯差分金字塔 旋轉不變性 主方向 部分放射不變性 在統計梯度方向直方圖時對直方圖進行了高斯平滑 sift特徵分為兩部分,第乙個是要檢測一幅影象中關鍵點的位置,第二個是要生成乙個描述子來表示這個點位置。名詞解釋 1...
HashMap原始碼系列 HashMap的屬性
public class hashmap extends abstractmap implements map,cloneable,serializable容載因子 容載因子越大,table陣列中儲存的資料越密集,碰撞的可能性就越大。容載因子越小,儲存越稀疏,碰撞的可能性就越小,不過浪費儲存空間。轉...