上一篇中咱們共同探討了HashMap,而且也提到了Hashtable與HashMap很類似,除了Hashtable是同步的以及不容許null值外。如今,趁熱打鐵,開始Hashtable的學習。數組
老規矩,先過一遍註釋。安全
任何非null的對象均可以做爲key或者value存入其中。函數
存入其中的key必須實現了hashCode以及equals方法。性能
與HashMap同樣,有兩個參數影響Hashtable的性能,初始容量initial capacity以及負載因子load factor。他們的做用於HashMap中的相同,詳細請看這篇文章學習
若是Hashtable中要存放不少鍵值對,那麼在一開始把他的初始容量設置的大點比較好。線程
Hashtable返回的迭代器即Iterator都是基於快速失敗機制fail-fast的。3d
不像其餘新的集合實現,Hashtable是同步的,因此在不須要考慮線程安全的狀況下,推薦使用HashMap替代Hashtable以得到更好的性能。若是須要一個高度線程安全的同步,則推薦使用ConcurrentHashMap代替Hashtable。(感受均可以把Hashtable從Jdk中刪掉了,奶奶不疼姥姥不愛的:joy:)。cdn
先來看一下它的屬性:對象
其實這些一看就知道了,可是咱們仍是一個個的說說。blog
其實Hashtable的存儲結構也是數組+鏈表的形式,咱們圖解一下:
能夠看到實際上是跟HashMap未樹化前的存儲結構相同。
先從構造函數看起
在上篇文章中,咱們說到,其實在HashMap中並無直接使用咱們傳入的參數initialCapacity,而是使用一個方法將其轉換成離其最近的2的n次方數字,可是Hashtable並非如此,在代碼中能夠看到,在構造函數中直接使用initialCapacity對table進行了初始化。而且隨機計算出了閾值threshold。
咱們屢次提到Hashtable是同步的,那這個同步體如今哪裏呢?就體如今下面:
看出來了嗎?其實就體如今這些方法前面加的關鍵字synchronized。
咱們直接來看擴容機制,不去看那些大同小異的put方法了。咱們看看rehash的源碼:
一樣的源碼中,先去根據舊的容量求出新的容量也就是table數組的大小。咱們注意到新的容量不是直接是舊的容量的二倍而是舊的容量的二倍加一
其次,咱們能夠注意到,Hashtable用了一個for循環對其中的每一個元素根據其Hash從新計算了其在新數組中的索引。
不須要考慮線程安全時用HashMap提升性能,須要考慮線程安全時用ConcurrentHashMap
同步體如今對每一個方法使用了synchronized關鍵字。
存儲結構是數組+鏈表
擴容時默認擴容爲原來的兩倍加一
擴容時在進行元素複製時對舊數組中存儲的每一個元素從新計算了索引並插入到新數組中。