我們一直知道HashMap是非線程安全的,HashTable是線程安全的,可這是為什么呢?先聊聊HashMap吧,想要了解它為什么是非線程安全的,我們得從它的原理著手。

jdk7中的HashMap

HashMap底層維護(hù)一個(gè)數(shù)組,數(shù)組中的每一項(xiàng)都是Entry

transient Entry<K,V>[] table;

我們向HashMap放置的對(duì)象實(shí)際上是放置在Entry數(shù)組中

而Map中的key、value則以Entry的形式存放在數(shù)組中

private static class Entry<K,V> implements Map.Entry<K,V> {    final int hash;    final K key;
    V value;    Entry<K,V> next;

而這個(gè)Entry應(yīng)該放在數(shù)組的哪一個(gè)位置上(這個(gè)位置通常稱為位桶或者h(yuǎn)ash桶,即hash值相同的Entry會(huì)放在同一位置,用鏈表相連),是通過(guò)key的hashCode來(lái)計(jì)算的。

iOS培訓(xùn),Swift培訓(xùn),蘋果開(kāi)發(fā)培訓(xùn),移動(dòng)開(kāi)發(fā)培訓(xùn)

當(dāng)兩個(gè)key通過(guò)hashcode計(jì)算是相同的時(shí)候,就會(huì)發(fā)生hash沖突,HashMap解決hash沖突的辦法是使用鏈表。

簡(jiǎn)而言之就是,如果該位置沒(méi)有對(duì)象,則將對(duì)象直接放到數(shù)組中,如果該位置有對(duì)象,順著存在此對(duì)象的鏈找(Map中不允許存在相同的key和value),如果不存在相同的,第一種情況:如果該鏈表擴(kuò)容了,則把對(duì)象放入到數(shù)組中,原先存放在數(shù)組中的數(shù)據(jù)放置該對(duì)象的后面。第二種情況:如果該鏈表沒(méi)有擴(kuò)容,則直接放到鏈表的最后。如果存在相同的,則進(jìn)行替換。

網(wǎng)友評(píng)論