posts - 2,  comments - 0,  trackbacks - 0
          關(guān)于兩者的區(qū)別,轉(zhuǎn)載內(nèi)容如下:

          1、Hashtable是Dictionary的子類,HashMap是Map接口的一個(gè)實(shí)現(xiàn)類;

          2、Hashtable中的方法是同步的,而HashMap中的方法在缺省情況下是非同步的。即是說,在多線程應(yīng)用程序中,不用專門的操作就安全地可以使用Hashtable了;而對(duì)于 HashMap,則需要額外的同步機(jī)制。但HashMap的同步問題可通過Collections的一個(gè)靜態(tài)方法得到解決:
          Map Collections.synchronizedMap(Map m)
          這個(gè)方法返回一個(gè)同步的Map,這個(gè)Map封裝了底層的HashMap的所有方法,使得底層的HashMap即使是在多線程的環(huán)境中也是安全的。

          3、在HashMap中,null可以作為鍵,這樣的鍵只有一個(gè);可以有一個(gè)或多個(gè)鍵所對(duì)應(yīng)的值為null。當(dāng)get()方法返回null值時(shí),即可以表示 HashMap中沒有該鍵,也可以表示該鍵所對(duì)應(yīng)的值為null。因此,在HashMap中不能由get()方法來判斷HashMap中是否存在某個(gè)鍵, 而應(yīng)該用containsKey()方法來判斷。

          4、其底層的實(shí)現(xiàn)機(jī)制不同,HashMap的訪問速度要快于Hashtable,因?yàn)樗恍枰M(jìn)行同步檢驗(yàn),建議在非多線程環(huán)境中使用HashMap代替Hashtable

          ==================== 分割線:JDK5幫助文檔的描述 ==================

          HashMap:

          基于哈希表的 Map 接口的實(shí)現(xiàn)。此實(shí)現(xiàn)提供所有可選的映射操作,并允許使用 null 值和 null 鍵。(除了不同步和允許使用 null 之外,HashMap 類與 Hashtable 大致相同。)此類不保證映射的順序,特別是它不保證該順序恒久不變。 


          此實(shí)現(xiàn)假定哈希函數(shù)將元素正確分布在各桶之間,可為基本操作(get 和 put)提供穩(wěn)定的性能。迭代集合視圖所需的時(shí)間與 HashMap 實(shí)例的“容量”(桶的數(shù)量)及其大小(鍵-值映射關(guān)系數(shù))的和成比例。所以,如果迭代性能很重要,則不要將初始容量設(shè)置得太高(或?qū)⒓虞d因子設(shè)置得太低)。

          HashMap 的實(shí)例有兩個(gè)參數(shù)影響其性能:初始容量和加載因子。容量是哈希表中桶的數(shù)量,初始容量只是哈希表在創(chuàng)建時(shí)的容量。加載因子 是哈希表在其容量自動(dòng)增加之前可以達(dá)到多滿的一種尺度。當(dāng)哈希表中的條目數(shù)超出了加載因子與當(dāng)前容量的乘積時(shí),通過調(diào)用 rehash 方法將容量翻倍。

          通常,默認(rèn)加載因子 (.75) 在時(shí)間和空間成本上尋求一種折衷。加載因子過高雖然減少了空間開銷,但同時(shí)也增加了查詢成本(在大多數(shù) HashMap 類的操作中,包括 get 和 put 操作,都反映了這一點(diǎn))。在設(shè)置初始容量時(shí)應(yīng)該考慮到映射中所需的條目數(shù)及其加載因子,以便最大限度地降低 rehash 操作次數(shù)。如果初始容量大于最大條目數(shù)除以加載因子,則不會(huì)發(fā)生 rehash 操作。

          如果很多映射關(guān)系要存儲(chǔ)在 HashMap 實(shí)例中,則相對(duì)于按需執(zhí)行自動(dòng)的 rehash 操作以增大表的容量來說,使用足夠大的初始容量創(chuàng)建它將使得映射關(guān)系能更有效地存儲(chǔ)。

          注意,此實(shí)現(xiàn)不是同步的。如果多個(gè)線程同時(shí)訪問此映射,而其中至少一個(gè)線程從結(jié)構(gòu)上修改了該映射,則它必須保持外部同步。(結(jié)構(gòu)上的修改是指添加或刪除一個(gè)或多個(gè)映射關(guān)系的操作;僅改變與實(shí)例已經(jīng)包含的鍵關(guān)聯(lián)的值不是結(jié)構(gòu)上的修改。)這一般通過對(duì)自然封裝該映射的對(duì)象進(jìn)行同步操作來完成。如果不存在這樣的對(duì)象,則應(yīng)該使用 Collections.synchronizedMap 方法來“包裝”該映射。最好在創(chuàng)建時(shí)完成這一操作,以防止對(duì)映射進(jìn)行意外的不同步訪問,如下所示:

           Map m = Collections.synchronizedMap(new HashMap(...));
           由所有此類的“集合視圖方法”所返回的迭代器都是快速失敗的:在迭代器創(chuàng)建之后,如果從結(jié)構(gòu)上對(duì)映射進(jìn)行修改,除非通過迭代器自身的 remove 或 add 方法,其他任何時(shí)間任何方式的修改,迭代器都將拋出 ConcurrentModificationException。因此,面對(duì)并發(fā)的修改,迭代器很快就會(huì)完全失敗,而不冒在將來不確定的時(shí)間任意發(fā)生不確定行為的風(fēng)險(xiǎn)。

          注意,迭代器的快速失敗行為不能得到保證,一般來說,存在不同步的并發(fā)修改時(shí),不可能作出任何堅(jiān)決的保證。快速失敗迭代器盡最大努力拋出 ConcurrentModificationException。因此,編寫依賴于此異常程序的方式是錯(cuò)誤的,正確做法是:迭代器的快速失敗行為應(yīng)該僅用于檢測(cè)程序錯(cuò)誤。 


          Hashtable:

          此類實(shí)現(xiàn)一個(gè)哈希表,該哈希表將鍵映射到相應(yīng)的值。任何非 null 對(duì)象都可以用作鍵或值

          為了成功地在哈希表中存儲(chǔ)和檢索對(duì)象,用作鍵的對(duì)象必須實(shí)現(xiàn) hashCode 方法和 equals 方法。

          Hashtable 的實(shí)例有兩個(gè)參數(shù)影響其性能:初始容量和加載因子。容量是哈希表中桶的數(shù)量,初始容量就是哈希表創(chuàng)建時(shí)的容量。注意,哈希表的狀態(tài)為 open:在發(fā)生“哈希沖突”的情況下,單個(gè)桶會(huì)存儲(chǔ)多個(gè)條目,這些條目必須按順序搜索。加載因子是對(duì)哈希表在其容量自動(dòng)增加之前可以達(dá)到多滿的一個(gè)尺度。初始容量和加載因子這兩個(gè)參數(shù)只是對(duì)該實(shí)現(xiàn)的提示。關(guān)于何時(shí)以及是否調(diào)用 rehash 方法的具體細(xì)節(jié)則依賴于該實(shí)現(xiàn)。

          通常,默認(rèn)加載因子(.75)在時(shí)間和空間成本上尋求一種折衷。加載因子過高雖然減少了空間開銷,但同時(shí)也增加了查找某個(gè)條目的時(shí)間(在大多數(shù) Hashtable 操作中,包括 get 和 put 操作,都反映了這一點(diǎn))。

          初始容量主要控制空間消耗與執(zhí)行 rehash 操作所需要的時(shí)間損耗之間的平衡。如果初始容量大于Hashtable 所包含的最大條目數(shù)除以加載因子,則永遠(yuǎn)不會(huì)發(fā)生 rehash 操作。但是,將初始容量設(shè)置太高可能會(huì)浪費(fèi)空間。

          如果很多條目要存儲(chǔ)在一個(gè) Hashtable 中,那么與根據(jù)需要執(zhí)行自動(dòng) rehashing 操作來增大表的容量的做法相比,使用足夠大的初始容量創(chuàng)建哈希表或許可以更有效地插入條目。

          下面這個(gè)示例創(chuàng)建了一個(gè)數(shù)字的哈希表。它將數(shù)字的名稱用作鍵:

          1 Hashtable numbers = new Hashtable();
          2 numbers.put("one"new Integer(1));
          3 numbers.put("two"new Integer(2));
          4 numbers.put("three"new Integer(3));

          要檢索一個(gè)數(shù)字,可以使用以下代碼:

          Integer n = (Integer)numbers.get("two");
          if (n != null) {
              System.out.println(
          "two = " + n);
          }


           自 Java 2 平臺(tái) v1.2 以來,此類已經(jīng)改進(jìn)為可以實(shí)現(xiàn) Map,因此它變成了 Java Collections Framework 的一部分。與新集合的實(shí)現(xiàn)不同,Hashtable 是同步的。

          由迭代器返回的 Iterator 和由所有 Hashtable 的“collection 視圖方法”返回的 Collection 的 listIterator 方法都是快速失敗 的:在創(chuàng)建 Iterator 之后,如果從結(jié)構(gòu)上對(duì) Hashtable 進(jìn)行修改,除非通過 Iterator 自身的移除或添加方法,否則在任何時(shí)間以任何方式對(duì)其進(jìn)行修改,Iterator 都將拋出 ConcurrentModificationException。因此,面對(duì)并發(fā)的修改,Iterator 很快就會(huì)完全失敗,而不冒在將來某個(gè)不確定的時(shí)間發(fā)生任意不確定行為的風(fēng)險(xiǎn)。由 Hashtable 的鍵和值方法返回的 Enumeration 不 是快速失敗的。

          注意,迭代器的快速失敗行為無法得到保證,因?yàn)橐话銇碚f,不可能對(duì)是否出現(xiàn)不同步并發(fā)修改做出任何硬性保證。快速失敗迭代器會(huì)盡最大努力拋出 ConcurrentModificationException。因此,為提高這類迭代器的正確性而編寫一個(gè)依賴于此異常的程序是錯(cuò)誤做法:迭代器的快速失敗行為應(yīng)該僅用于檢測(cè)程序錯(cuò)誤。

          posted on 2009-04-23 21:49 iConnect 閱讀(337) 評(píng)論(0)  編輯  收藏 所屬分類: Java

          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          <2025年6月>
          25262728293031
          1234567
          891011121314
          15161718192021
          22232425262728
          293012345

          常用鏈接

          留言簿(2)

          文章分類(17)

          文章檔案(16)

          收藏夾(17)

          搜索

          •  

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 崇礼县| 屏东市| 怀集县| 莱芜市| 收藏| 吉隆县| 连云港市| 靖西县| 新乐市| 新昌县| 塘沽区| 湟源县| 昌江| 克什克腾旗| 通道| 神池县| 涿州市| 西乌珠穆沁旗| 如东县| 霍邱县| 杨浦区| 清原| 右玉县| 乳山市| 长汀县| 西盟| 林周县| 甘泉县| 舟曲县| 夏邑县| 高碑店市| 中超| 安康市| 五莲县| 昭觉县| 获嘉县| 芮城县| 邻水| 庄浪县| 铅山县| 延长县|