基於雜湊表的 map 介面的實現。此實現提供所有可選的對映操作,並允許使用 null 值和 null 鍵。(除了非同步和允許使用 null 之外,hashmap 類與 hashtable 大致相同。)此類不保證對映的順序,特別是它不保證該順序恆久不變。 此實現假定雜湊函式將元素適當地分布在各桶之間,可為基本操作(get 和 put)提供穩定的效能。迭代 collection 檢視所需的時間與 hashmap 例項的「容量」(桶的數量)及其大小(鍵-值對映關係數)成比例。所以,如果迭代效能很重要,則不要將初始容量設定得太高(或將載入因子設定得太低)。
mapmap = new hashmap<>();
map.get("");
map.put("",null);
map.clear();
map.isempty();
...
類實現乙個雜湊表,該雜湊表將鍵對映到相應的值。任何非 null 物件都可以用作鍵或值。為了成功地在雜湊表中儲存和獲取物件,用作鍵的物件必須實現 hashcode 方法和 equals 方法。
mapmap = new hashtable<>();
map.get("");
map.put("",null);
map.clear();
map.isempty();
...
concurrenthashmap繼承abstractmap,實現了concurrentmap介面。同時concurrentmap介面繼承map介面。簡單來說,concurrenthashmap屬於解決併發情況下的類。擁有hashtable和hashmap的優勢。
mapmap = new concurrenthashmap<>();
map.get("");
map.put("",null);
map.clear();
map.isempty();
...
咋一看hashmap、hashtable、concurrenthashmap用法幾乎一致,畢竟都是實現了map介面,日常使用的也就是map介面的方法。
重點就是它們各自對實現map介面具有差異。
下面我們以map的put方法簡單敘述一下它們的執行緒安全性
hashmap
public v put(k key, v value)
......
if ((p = tab[i = (n - 1) & hash]) == null)
tab[i] = newnode(hash, key, value, null);
else
......
node(int hash, k key, v value, nodenext)
當hashmap執行put時,會走
tab[i] = newnode(hash, key, value, null);
為map建立乙個新的node節點。節點的hash值是根據key的值計算出來的。node為hashmap的乙個內部類——內部實體物件。乙個put的操作背後是有多個執行緒一起進行操作的。底層有乙個cache,jvm是先把具體的key和value放在快取的entry中,entry是乙個單鏈。node就和這個單鏈上的結點一一對應起來。這麼看下來,難怪說是效能好,執行緒不安全,光這麼乙個put操作,沒有看到任何執行緒安全操作的步驟啊。多執行緒同時操作這個put方法,在entry這個單鏈中,誰能保證下乙個結點儲存的是乙個正確的資料。
hashtable
public
synchronized v put(k key, v value)
// makes sure the key is not already in the hashtable.
entry,?> tab = table;
int hash = key.hashcode();
int index = (hash & 0x7fffffff) % tab.length;
@suppresswarnings("unchecked")
entryentry = (entry)tab[index];
for(; entry != null ; entry = entry.next)
}addentry(hash, key, value, index);
return
null;
}
此時hashtable原始碼一貼,立馬清晰可見,put方法上加了乙個synchronized,這不就是乙個同步**塊麼。具體**不用分析,大家也就知道了,哦哦~~這個put方法被synchronized修飾了,是執行緒安全的,多執行緒同時執行它,方法是乙個乙個一次執行的,不會出現任何問題。但是這樣也帶來了乙個弊端,效能效率太慢了。。。
如何可以看到hashmap的執行結果永遠是不會正確的,就是因為它在put時,node所對應的entry中的hash被衝撞掉了。其他兩種map都是安全的,結果都是正確的。不過現如今已經不推薦使用hashtable了,如果要使用安全的map,就用concurrenthashmap。
HashMap原始碼簡單分析
1 還是老習慣,一邊看,一邊新增注釋,希望堅持下去,hashmap的基本原始碼進行了分析,內部一些介面和設計還沒來得及看23 一 成員 45 1 transient entry table 67 hashmap內部維護了乙個內部類 entry,用來存放鍵值對,這個entry實現了map.entry這...
HashMap 底層分析
更多 hashmap 與 concurrenthashmap 相關請檢視這裡。以下基於 jdk1.7 分析。如圖所示,hashmap 底層是基於陣列和鍊錶實現的。其中有兩個重要的引數 容量的預設大小是 16,負載因子是 0.75,當hashmap的size 16 0.75時就會發生擴容 容量和負載因...
HashMap 底層分析
以下基於 jdk1.7 分析。hashmap 底層是基於陣列和鍊錶實現的。其中有兩個重要的引數 容量的預設大小是 16,負載因子是 0.75,當hashmap的size 16 0.75時就會發生擴容 容量和負載因子都可以自由調整 首先會將傳入的 key 做hash運算計算出 hashcode,然後根...