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

jdk7中的HashMap

HashMap底層維護一個數(shù)組,數(shù)組中的每一項都是Entry

transient Entry<K,V>[] table;

我們向HashMap放置的對象實際上是放置在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;

而這個Entry應(yīng)該放在數(shù)組的哪一個位置上(這個位置通常稱為位桶或者hash桶,即hash值相同的Entry會放在同一位置,用鏈表相連),是通過key的hashCode來計算的。

iOS培訓,Swift培訓,蘋果開發(fā)培訓,移動開發(fā)培訓

當兩個key通過hashcode計算是相同的時候,就會發(fā)生hash沖突,HashMap解決hash沖突的辦法是使用鏈表。

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

網(wǎng)友評論