hashmap hashtable 的區別

來源:互聯網
上載者:User

標籤:

Hashtable 和 HashMap 做為 Map 的基本特性兩者都實現了Map介面,基本特性相同-          對同一個Key,只會有一個對應的value值存在-          如何算是同一個Key? 首先,兩個key對象的hash值相同,其次,key對象的equals方法返回真內部資料結構Hashtable和HashMap的內部資料結構相似

 其基本內部資料結構是一個Entry數組 (transient Entry[] table)-          數組元素為實現Map.Entry<K,V>介面的類,Hashtable和HashMap各自實現了自己的Entry類。-          Entry包含一個Key-value對,以及一個next指標指向另一個Entry。多個Entry可以組成一個單向鏈表。常用操作資料插入操作: put(key,value)-          根據Key的hash值計算出該Entry所應存放的位置(數組下標)-          若該數組元素為空白,直接放置Entry到此處-          若多個不同的Key所計算得到的數組下標相同,新加入的Key-value對(Entry)會被加入到Entry單向鏈表中。Hashtable和HashMap都是將其插入鏈表首部.-          若已經有相同的Key存在於這個鏈表中,則,新的value值會取代老的value-          當Map中存放的Entry數量超過其限制( 數組長度 * 負荷因子)時,Map將自動重新調整數組大小並重新對Entry進行散列  資料尋找:get(key)-          根據Key的hash值計算出該Entry對所應存放的位置(數組下標)-          得到該位置的第一個Entry對象,比較key和Entry.key,若hash值相同,並且equals為真,則該Entry是我們要找的Key-value對,否則繼續沿next指標構成的單向鏈表尋找 資料移除:remove(key)-          按照上述資料尋找的方式找到key所在的Entry對象,將其移除,並保持Entry單向鏈表的連通性Hashtable 和 HashMap 的比較

 

  Hashtable HashMap
並行作業 使用同步機制,實際應用程式中,僅僅是Hashtable本身的同步並不能保證程式在並行作業下的正確性,需要高層次的並發保護。下面的代碼試圖在key所對應的value值等於x的情況下修改value為x+1{ value = hashTable.get(key);   if(value.intValue()== x){hashTable.put(key,      new Integer(value.intValue()+1));   }}如2個線程同時執行以上代碼,可能放入不是x+1,而是x+2. 沒有同步機制,需要使用者自己進行並發存取控制
資料遍曆的方式 Iterator 和 Enumeration Iterator
是否支援fast-fail 用Iterator遍曆,支援fast-fail用Enumeration不支援fast-fail. 支援fast-fail
是否接受值為null的Key 或Value? 不接受 接受
根據hash值計算數組下標的演算法 當數組長度較小,並且Key的hash值低位元值分散不均勻時,不同的hash值計算得到相同下標值的幾率較高 hash = key.hashCode();index=(hash&0x7FFFFFFF) % tab.length; 優於hashtable,通過對Key的hash做移位元運算和位的與運算,使其能更廣泛地分散到數組的不同位置 hash = hash (k);index = indexFor(hash, table.length); static int hash(Object x) { int h = x.hashCode();h += ~(h << 9); h ^= (h >>> 14);  h += (h << 4); h ^= (h >>> 10); return h;}static int indexFor(int h, int length) {return h & (length-1);} 
Entry數組的長度 Ø         預設初始長度為11,Ø         初始化時可以指定initial capacity Ø         預設初始長度為16,Ø         長度始終保持2的n次方Ø         初始化時可以指定initial capacity,若不是2的次方,HashMap將選取第一個大於initial capacity 的2n次方值作為其初始長度
LoadFactor負荷因子 0.75
負荷超過(loadFactor * 數組長度)時,內部資料的調整方式 擴充數組:2*原數組長度+1 擴充數組: 原數組長度 * 2
兩者都會重新根據Key的hash值計算其在數組中的新位置,重新放置。演算法相似,時間、空間效率相同
 一般情況下,HashMap能夠比Hashtable工作的更好、更快,主要得益於它的散列演算法,以及沒有同步。應用程式一般在更高的層面上實 現了保護機制,而不是依賴於這些底層資料結構的同步,因此,HashMap能夠在大多應用中滿足需要。推薦使用HashMap,如果需要同步,可以使用同 步工具類將其轉換成支援同步的HashMap。Map的效率Map的效率與Entry數組大小及負荷因子的選取有密切關係。選取適當的數組大小有利於Key-value對的散列分布,並且,如果數組足夠 大,將有效減少重新調整數組的次數,提高效率。較小的負荷因子將佔用更多的空間,但降低衝突的可能性,從而將加快訪問和更新的速度。另外,Key的hash值本身如果能保證較好的散列性,也有益於提高Map的讀寫效率。在effective java中,對hash()的重載有好的建議。關於如何提高Map的執行效率,可參考《Java Map 集合類簡介》http://www.oracle.com/technology/global/cn/pub/articles/maps1.html 。 辨析 “Hashtable和HashMap的區別主要是前者是同步的,後者是快速失敗機制保證不會出現多線程並發錯誤(Fast-Fail)。”,這是一個被很多文章轉載過的概念,但其描述並不準確,容易引起誤會。實質上,Fast-fail與同步保護的是兩種不同情況下的並發,兩者不能拿來做比較。Hashtable是同步的,在執行get,put,remove,size,clear等一次性讀寫操作時,使用了同步機制,避免了多個線程 同時讀寫Hashtable。但同步機制並不能避免在iterator或Enumeration遍曆過程中其他線程對Hashtable的put、 remove、clear操作,這些寫操作都會被毫無阻攔得成功執行。快速失敗機制主要目的在於使iterator遍曆數組的線程能及時發現其他線程對Map的修改(如put、remove、clear等),因 此,fast-fail並不能保證所有情況下的多線程並發錯誤,只能保護iterator遍曆過程中的iterator.next()與寫並發.其次,Hashtable的iterator遍曆方式也是支援fast-fail的,不能說它沒有快速失敗機制。寫一個簡單的常式就可以證明這 一點,一個線程做iterator遍曆,另一個線程向hashtable中put新的key和value,很容易就會觀察到fast-fail 機制報告 ConcurrentModificationException

hashmap hashtable 的區別

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.