老生常談的問題——Hashtable和HashMap有什麼區別數組
你們通常都能說出幾條,好比Hashtable是線程安全的,不支持null做爲key和value值等等。那麼,要仔細瞭解這個問題仍是直接從Hashtable的源碼入手。安全
先列一下我找到的區別:多線程
- 繼承類不一樣,Hashtable繼承的是Dictionary這是一個廢棄類,而HashMap繼承的是AbstractMap
- 產生時間不一樣,Hashtable自JDK1.0版本就有了,而HashMap是JDK1.2才加入的,同時Hashtable可能由於歷史緣由並非咱們習慣的駝峯法命名的
- Hashtable比HashMap多提供了elments()方法用於返回此Hashtable中的value的枚舉
- Hashtable既不支持null key也不支持null value
- Hashtable的默認大小是11,擴大的邏輯是*2+1,對於給定大小不會作擴展。而HashMap是16,擴大時*2,初始大小會轉換成剛好大於等於的2的指數次冪
- Hashtable中的遍歷操做是從高位開始的,而HashMap是從低位開始
- Hashtable處理衝突元素時插入到鏈表頭部,而HashMap是插入到鏈表尾部
- Hashtable的hashcode方法計算全部entry的hashcode總和,HashMap沒有這樣的方法,同時HashMap在計算hash值時會用高位右移16位與低位異或來打散散列值,避免位與操做形成衝突過多
- Hashtable每一次定位都要作一次完整的除法取餘數,而HashMap使用的是與數組大小-1的位與計算,效率高不少
- Hashtable的方法都加上了synchronized是線程安全的方法,而HashMap不是,因此單線程時前者額外開銷很大。JDK8之後Hashtable也用了modCount來保證在遍歷過程當中其餘線程修改對象的fast-fail機制。可是,即便是多線程環境下,依然應該優先選擇對HashMap進行一些特殊處理而不是用Hashtable,由於全部方法都加上synchronized的程序併發性不好。實際上就我我的經驗而言,在一些特定的具體狀況下,好比大規模寫入key值連續數據(出自今年的第四屆阿里中間件性能挑戰賽複賽題),鏈表法解決衝突性能可能不如開放地址法,即便加上了紅黑樹。因此說對於一些對極致壓榨性能的狀況下,適當的能夠拋棄一些通用的集合而嘗試自由發揮造輪子。
首先從最上方的註釋中能夠看到Hashtable自JDK1.0版本就有了,而HashMap是JDK1.2才加入的。觀察一下類的聲明,咱們能夠看到他們繼承的類也是不一樣的,Hashtable繼承的是Dictionary,Dictionary這個類從註釋上寫着已是obsolete被廢棄了,因此連帶Hashtable也基本不用了。Hashtable也有元素個數,數組大小,負載因子這些屬性,不用元素個數用的是count不是size。也是使用鏈表法來解決衝突。併發