hashmap
是乙個雜湊表, 它儲存的內容是鍵值對(key - value)
對映。
hashmap
繼承於abstractmap
, 實現了map
,cloneable
,serializable
介面。
hashmap
不是執行緒安全的, 不適用於多執行緒中, 此外,hashmap
中的對映不是有序的。
hashmap
裡面是乙個陣列,然後陣列中每個元素是乙個單項鍊表。
圖中entry
包含四個屬性,key
,value
,hash
值和用於單項鍊表的next
。
key
值允許為空,value
允許為空。
重要引數/**
* 允許空的key值
*/public
static
void
putkeynull()
/** * 允許空的value值
*/public
static
void
putvaluenull()
執行結果:
entryset==
==key==
==null==
==value====1
====hash====0
entryset==
==key====1
====value==
==null==
==hash==
==49
capacity
和loadfactor
。
capacity
當前陣列容量,始終保持 2^n,預設值為1<<4
,最大為1<<16
, 可以擴容,擴容後陣列大小為當前的 2 倍。
loadfactor
負載因子,預設為 0.75。
threshold
擴容的閾值,等於capacity * loadfactor
。
static
final
int default_initial_capacity =
1<<4;
static
final
int maximum_capacity =
1<<30;
static
final
float default_load_factor =
0.75f
;
hashmap
的put
方法:
public v put
(k key, v value)
//第三個引數 onlyifabsent 如果是 true,那麼只有在不存在該 key 時才會進行 put 操作
final v putval
(int hash, k key, v value,
boolean onlyifabsent,
boolean evict)
if(e.hash == hash &&
((k = e.key)
== key ||
(key != null && key.
equals
(k))))
break
; p = e;}}
// e!=null 說明存在舊值的key與要插入的key"相等"
// 對於我們分析的put操作,下面這個 if 其實就是進行 "值覆蓋",然後返回舊值
if(e != null)
}++modcount;
// 如果 hashmap 由於新插入這個值導致 size 已經超過了閾值,需要進行擴容if(
++size > threshold)
resize()
;afternodeinsertion
(evict)
;return null;
}接下來看 hashmap 的 resize 方法
final node
resize()
elseif(
(newcap = oldcap <<1)
< maximum_capacity &&
oldcap >= default_initial_capacity)
newthr = oldthr <<1;
// double threshold
}else
if(oldthr >0)
// 對應使用 new hashmap(int initialcapacity) 初始化後,第一次 put 的時候
newcap = oldthr;
else
// 用新的陣列大小初始化新的陣列
if(newthr ==0)
threshold = newthr;
@suppresswarnings()
node
newtab =
(node
)new
node
[newcap]
; table = newtab;
// 如果是初始化陣列,到這裡就結束了,返回 newtab 即可
if(oldtab != null)
else
}while
((e = next)
!= null);if
(lotail != null)
if(hitail != null)}}
}}return newtab;
}
hashmap
的get
方法
1.計算key
的hash
值,根據hash
值找到對應陣列下標:hash & (length-1)
2.判斷陣列該位置處的元素是否剛好就是我們要找的,如果不是,走第三步
3.判斷該元素型別是否是treenode
,如果是,用紅黑樹的方法取資料,如果不是,走第四步
4.遍歷鍊錶,直到找到相等(==或equals)的 key
public v get
(object key)
final node
getnode
(int hash, object key)
while
((e = e.next)
!= null);}
}return null;
}
HashMap原始碼分析
public hashmap int initialcapacity,float loadfactor 2 接下來是重要的put方法,put方法用於將鍵值對儲存到map中,讓我們來具體分析一下。public v put k key,v value if key null 若key為null,則將va...
HashMap 原始碼分析
1 getentry object key 方法 final entrygetentry object key return null 根據key的hash值計算出索引,得到table中的位置,然後遍歷table處的鍊錶 for entrye table indexfor hash,table.le...
HashMap原始碼分析
public v put k key,v value if key null return putfornullkey value int hash hash key int i indexfor hash,table.length for entrye table i e null e e.nex...