![](/img/trans.png)
[英]Differences between .Net Hashtable, Java Hashtable & HashMap
[英]What are the differences between a HashMap and a Hashtable in Java?
Hashtable
是synchronized ,而HashMap
不是。 這使得HashMap
更適合非線程應用程序,因為未同步的對象通常比同步的對象執行得更好。
Hashtable
不允許null
鍵或值。 HashMap
允許一個null
鍵和任意數量的null
值。
HashMap 的子類之一是LinkedHashMap
,因此如果您想要可預測的迭代順序(默認情況下是插入順序),您可以輕松地將HashMap
換成LinkedHashMap
。 如果您使用Hashtable
這將不會那么容易。
由於同步對您來說不是問題,我建議使用HashMap
。 如果同步成為一個問題,您還可以查看ConcurrentHashMap
。
請注意,很多答案都表明 Hashtable 是同步的。 在實踐中,這給你帶來的影響很小。 同步是在訪問器/修改器方法上,將阻止兩個線程同時添加或從映射中刪除,但在現實世界中,您經常需要額外的同步。
一個非常常見的習慣用法是“先檢查再放”——即在Map
查找條目,如果它不存在則添加它。 無論您使用Hashtable
還是HashMap
這都不是原子操作。
可以通過以下方式獲得等效同步的HashMap
:
Collections.synchronizedMap(myMap);
但是為了正確實現這個邏輯,你需要額外的表單同步:
synchronized(myMap) {
if (!myMap.containsKey("tomato"))
myMap.put("tomato", "red");
}
即使迭代Hashtable
的條目(或由Collections.synchronizedMap
獲得的HashMap
)也不是線程安全的,除非您還保護Map
不被附加同步修改。
ConcurrentMap
接口的實現(例如ConcurrentHashMap
)通過包含線程安全的 check-then-act 語義解決了其中的一些問題,例如:
ConcurrentMap.putIfAbsent(key, value);
Hashtable
被認為是遺留代碼。 沒有什么有關的Hashtable
不能用做HashMap
或派生HashMap
,因此對於新的代碼,我看不到回去的任何理由Hashtable
。
這個問題在面試中經常被問到,以檢查候選人是否理解集合類的正確用法,以及是否知道可用的替代解決方案。
HashMap
類大致等同於Hashtable
,除了它是非同步的並且允許空值。 ( HashMap
允許 null 值作為鍵和值,而Hashtable
不允許null
s)。HashMap
不保證映射的順序會隨着時間的推移保持不變。HashMap
是非同步的,而Hashtable
是同步的。HashMap
迭代器是故障安全的,而Hashtable
的枚舉器則不是,如果任何其他線程通過添加或刪除除Iterator
自己的remove()
方法之外的任何元素在結構上修改映射,則拋出ConcurrentModificationException
。 但這不是保證的行為,JVM 會盡最大努力完成。一些重要術語的注意事項:
Hashtable
執行更新之前,任何線程都必須獲取對象上的鎖,而其他線程將等待釋放鎖。set
方法,因為它不會“從結構上”修改集合。 但是,如果在調用set
之前,集合已在結構上進行了修改,則會拋出IllegalArgumentException
。 HashMap
可以通過以下方式同步
Map m = Collections.synchronizeMap(hashMap);
Map 提供 Collection 視圖,而不是通過 Enumeration 對象直接支持迭代。 集合視圖極大地增強了界面的表現力,本節稍后將對此進行討論。 Map 允許您迭代鍵、值或鍵值對; Hashtable
不提供第三個選項。 Map 提供了一種在迭代過程中刪除條目的安全方法; Hashtable
沒有。 最后,Map 修復了Hashtable
接口中的一個小缺陷。 Hashtable
有一個稱為 contains 的方法,如果Hashtable
包含給定值,則返回 true。 鑒於其名稱,如果Hashtable
包含給定的鍵,您會期望此方法返回 true,因為鍵是Hashtable
的主要訪問機制。 Map 接口通過重命名方法containsValue
消除了這種混淆。 此外,這提高了接口的一致性—— containsValue
並行containsKey
。
HashMap
: Map
接口的一個實現,它使用哈希碼來索引一個數組。 Hashtable
:嗨,1998 年打電話。 他們希望恢復他們的集合 API。
不過說真的,你最好完全遠離Hashtable
。 對於單線程應用程序,您不需要額外的同步開銷。 對於高度並發的應用程序,偏執的同步可能會導致飢餓、死鎖或不必要的垃圾收集暫停。 就像 Tim Howland 指出的那樣,您可以改用ConcurrentHashMap
。
請記住,在引入 Java Collections Framework (JCF) 之前, HashTable
是遺留類,后來經過改造以實現Map
接口。 Vector
和Stack
。
因此,在新代碼中始終遠離它們,因為正如其他人指出的那樣,JCF 中總是有更好的選擇。
這是您會發現有用的Java 集合備忘單。 請注意,灰色塊包含遺留類 HashTable、Vector 和 Stack。
已經發布了許多好的答案。 我正在添加一些新觀點並對其進行總結。
HashMap
和Hashtable
都用於以鍵值形式存儲數據。 兩者都使用散列技術來存儲唯一鍵。 但是下面給出的 HashMap 和 Hashtable 類之間存在許多差異。
哈希表
HashMap
是非同步的。 它不是線程安全的,如果沒有適當的同步代碼,就不能在許多線程之間共享。HashMap
允許一個空鍵和多個空值。HashMap
是 JDK 1.2 中引入的一個新類。HashMap
很快。HashMap
同步Map m = Collections.synchronizedMap(HashMap);
HashMap
被迭代器遍歷。HashMap
迭代器是快速失敗的。HashMap
繼承了 AbstractMap 類。哈希表
Hashtable
是同步的。 它是線程安全的,可以與多個線程共享。Hashtable
不允許空鍵或值。Hashtable
是一個遺留類。Hashtable
很慢。Hashtable
是內部同步的,不能不同步。Hashtable
由 Enumerator 和 Iterator 遍歷。Hashtable
枚舉器不是快速失敗的。Hashtable
繼承了 Dictionary 類。看看這張圖表。 它提供了不同數據結構之間的比較以及HashMap
和Hashtable
。 比較准確、清晰且易於理解。
除了 izb 所說的, HashMap
允許空值,而Hashtable
不允許。
另請注意, Hashtable
擴展了Dictionary
類,作為Javadocs狀態,該類已過時並已被Map
接口取代。
Hashtable
與HashMap
類似,具有類似的接口。 建議您使用HashMap
,除非您需要支持遺留應用程序或需要同步,因為Hashtables
方法是同步的。 因此,在您不是多線程的情況下, HashMaps
是您最好的選擇。
Hashtable
是同步的,而HashMap
不是。 這使得Hashtable
比Hashmap
慢。
對於單線程應用程序,請使用HashMap
因為它們在功能方面是相同的。
hashtable 和 hashmap 之間的另一個主要區別是 HashMap 中的 Iterator 是快速失敗的,而 Hashtable 的枚舉器不是,如果任何其他線程通過添加或刪除除 Iterator 自己的 remove() 方法之外的任何元素在結構上修改映射,則拋出 ConcurrentModificationException。 但這不是保證的行為,將由 JVM 盡最大努力完成。”
我的來源: http : //javarevisited.blogspot.com/2010/10/difference-between-hashmap-and.html
除了這里已經提到的所有其他重要方面之外,Collections API(例如 Map 接口)一直在修改以符合 Java 規范的“最新和最好的”補充。
例如比較 Java 5 Map 迭代:
for (Elem elem : map.keys()) {
elem.doSth();
}
與舊的 Hashtable 方法相比:
for (Enumeration en = htable.keys(); en.hasMoreElements(); ) {
Elem elem = (Elem) en.nextElement();
elem.doSth();
}
在 Java 1.8 中,我們還承諾能夠像使用古老的腳本語言一樣構造和訪問 HashMap:
Map<String,Integer> map = { "orange" : 12, "apples" : 15 };
map["apples"];
更新:不,他們不會在 1.8 中登陸... :(
HashTable是同步的,如果您在單線程中使用它,您可以使用HashMap ,這是一個非同步版本。 未同步的對象通常性能更高一些。 順便說一下,如果多個線程並發訪問一個HashMap,並且至少有一個線程在結構上修改了映射,則必須在外部進行同步。 您可以使用以下方法將未同步的地圖包裝在同步地圖中:
Map m = Collections.synchronizedMap(new HashMap(...));
HashTable 只能包含非空對象作為鍵或值。 HashMap 可以包含一個空鍵和一個空值。
Map 返回的迭代器是快速失敗的,如果在迭代器創建后的任何時間對映射進行結構修改,除了通過迭代器自己的 remove 方法之外的任何方式,迭代器都會拋出ConcurrentModificationException
。 因此,面對並發修改,迭代器快速而干凈地失敗,而不是在未來不確定的時間冒着任意、非確定性行為的風險。 而由 Hashtable 的鍵和元素方法返回的枚舉不是快速失敗的。
HashTable 和 HashMap 是Java Collections Framework 的成員(從 Java 2 平台 v1.2 開始,HashTable 被改造以實現 Map 接口)。
HashTable 被認為是遺留代碼,如果需要線程安全的高並發實現,文檔建議使用ConcurrentHashMap代替 Hashtable。
HashMap 不保證元素返回的順序。 對於 HashTable 我猜它是一樣的,但我不完全確定,我沒有找到明確說明的資源。
HashMap
和Hashtable
也有顯着的算法差異。 之前沒有人提到過這一點,所以這就是我提出它的原因。 HashMap
將構建一個大小為 2 次方的哈希表,動態增加它,以便在任何存儲桶中最多有大約 8 個元素(沖突),並且對於一般元素類型將非常好地攪動元素。 但是,如果您知道自己在做什么,則Hashtable
實現可以更好地控制散列,即您可以使用例如最接近您的值域大小的素數來修復表大小,這將導致比 HashMap 更好的性能,即更少某些情況下的碰撞。
除了這個問題中廣泛討論的明顯差異之外,我將 Hashtable 視為“手動驅動”汽車,您可以更好地控制散列,而 HashMap 作為“自動驅動”對應物,通常性能良好。
根據這里的信息,我建議使用 HashMap。 我認為最大的優點是 Java 會阻止你在迭代時修改它,除非你通過迭代器來做。
Collection
——有時也稱為容器——只是一個將多個元素組合成一個單元的對象。 Collection
用於存儲、檢索、操作和交流聚合數據。 集合框架W是用於表示和操作集合的統一架構。
HashMap
JDK1.2
和 Hashtable JDK1.0
都用於表示一組以<Key, Value>
對表示的對象。 每個<Key, Value>
對稱為Entry
對象。 Entries 的集合由HashMap
和Hashtable
的對象引用。 集合中的鍵必須是唯一的或獨特的。 [因為它們用於檢索特定鍵的映射值。 集合中的值可以重復。]
«超類、遺留和集合框架成員
Hashtable 是JDK1.0
引入的遺留類,是Dictionary 類的子類。 從JDK1.2
重新設計Hashtable,實現Map接口,成為集合框架的成員。 HashMap 從它在JDK1.2
引入開始就是 Java Collection Framework 的成員。 HashMap 是 AbstractMap 類的子類。
public class Hashtable<K,V> extends Dictionary<K,V> implements Map<K,V>, Cloneable, Serializable { ... }
public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable { ... }
«初始容量和負載系數
容量是哈希表中的桶數,初始容量就是哈希表創建時的容量。 注意哈希表是開放的:在“ hash
collision
”的情況下,單個桶存儲多個條目,必須順序搜索。 負載因子是衡量哈希表在其容量自動增加之前允許達到多滿的指標。
HashMap 使用默認初始容量(16)和默認負載因子(0.75)構造一個空哈希表。 其中 Hashtable 構造具有默認初始容量(11)和負載因子/填充率 (0.75) 的空哈希表。
«發生哈希沖突時的結構修改
HashMap
, Hashtable
在哈希沖突的情況下,它們將映射條目存儲在鏈表中。 從 Java8 for HashMap
如果哈希桶增長超過某個閾值,該桶將從linked list of entries to a balanced tree
切換linked list of entries to a balanced tree
。 將最壞情況的性能從 O(n) 提高到 O(log n)。 在將列表轉換為二叉樹時,哈希碼用作分支變量。 如果在同一個桶中有兩個不同的哈希碼,一個被認為更大並且在樹的右邊,另一個在左邊。 但是當兩個哈希碼相等時, HashMap
假設鍵是可比較的,並比較鍵來確定方向,以便可以保持某種順序。 使HashMap
的鍵具有可比性是一個很好的做法。 如果桶大小達到TREEIFY_THRESHOLD = 8
則在添加條目時將條目的TREEIFY_THRESHOLD = 8
轉換為平衡樹,在刪除小於TREEIFY_THRESHOLD
且最多UNTREEIFY_THRESHOLD = 6
的條目時,會將平衡樹重新轉換為條目的鏈表。 Java 8 SRC ,堆棧
«集合視圖迭代,Fail-Fast 和 Fail-Safe
+--------------------+-----------+-------------+
| | Iterator | Enumeration |
+--------------------+-----------+-------------+
| Hashtable | fail-fast | safe |
+--------------------+-----------+-------------+
| HashMap | fail-fast | fail-fast |
+--------------------+-----------+-------------+
| ConcurrentHashMap | safe | safe |
+--------------------+-----------+-------------+
Iterator
本質上是快速失敗的。 即,如果在迭代時修改集合而不是它自己的 remove() 方法,它會拋出 ConcurrentModificationException。 Enumeration
本質上是故障安全的。 如果在迭代時修改了集合,它不會拋出任何異常。
根據 Java API Docs,Iterator 總是優於 Enumeration。
注意:枚舉接口的功能由迭代器接口復制。 此外,Iterator 添加了一個可選的刪除操作,並具有較短的方法名稱。 新的實現應該考慮使用 Iterator 而不是 Enumeration。
在Java 5 中引入了 ConcurrentMap 接口: ConcurrentHashMap
- 一個由哈希表支持的高並發、高性能ConcurrentMap
實現。 此實現在執行檢索時從不阻塞,並允許客戶端選擇更新的並發級別。 它旨在替代Hashtable
:除了實現ConcurrentMap
,它還支持Hashtable
特有的所有“遺留”方法。
每個HashMapEntry
的值都是可變的,從而確保競爭修改和后續讀取的細粒度一致性; 每次讀取都反映了最近完成的更新
迭代器和枚舉是故障安全的——反映自迭代器/枚舉創建以來某個時刻的狀態; 這允許以降低一致性為代價的同時讀取和修改。 它們不會拋出 ConcurrentModificationException。 然而,迭代器被設計為一次只能被一個線程使用。
與Hashtable
類似但與HashMap
不同的是,此類不允許將 null 用作鍵或值。
public static void main(String[] args) {
//HashMap<String, Integer> hash = new HashMap<String, Integer>();
Hashtable<String, Integer> hash = new Hashtable<String, Integer>();
//ConcurrentHashMap<String, Integer> hash = new ConcurrentHashMap<>();
new Thread() {
@Override public void run() {
try {
for (int i = 10; i < 20; i++) {
sleepThread(1);
System.out.println("T1 :- Key"+i);
hash.put("Key"+i, i);
}
System.out.println( System.identityHashCode( hash ) );
} catch ( Exception e ) {
e.printStackTrace();
}
}
}.start();
new Thread() {
@Override public void run() {
try {
sleepThread(5);
// ConcurrentHashMap traverse using Iterator, Enumeration is Fail-Safe.
// Hashtable traverse using Enumeration is Fail-Safe, Iterator is Fail-Fast.
for (Enumeration<String> e = hash.keys(); e.hasMoreElements(); ) {
sleepThread(1);
System.out.println("T2 : "+ e.nextElement());
}
// HashMap traverse using Iterator, Enumeration is Fail-Fast.
/*
for (Iterator< Entry<String, Integer> > it = hash.entrySet().iterator(); it.hasNext(); ) {
sleepThread(1);
System.out.println("T2 : "+ it.next());
// ConcurrentModificationException at java.util.Hashtable$Enumerator.next
}
*/
/*
Set< Entry<String, Integer> > entrySet = hash.entrySet();
Iterator< Entry<String, Integer> > it = entrySet.iterator();
Enumeration<Entry<String, Integer>> entryEnumeration = Collections.enumeration( entrySet );
while( entryEnumeration.hasMoreElements() ) {
sleepThread(1);
Entry<String, Integer> nextElement = entryEnumeration.nextElement();
System.out.println("T2 : "+ nextElement.getKey() +" : "+ nextElement.getValue() );
//java.util.ConcurrentModificationException at java.util.HashMap$HashIterator.nextNode
// at java.util.HashMap$EntryIterator.next
// at java.util.Collections$3.nextElement
}
*/
} catch ( Exception e ) {
e.printStackTrace();
}
}
}.start();
Map<String, String> unmodifiableMap = Collections.unmodifiableMap( map );
try {
unmodifiableMap.put("key4", "unmodifiableMap");
} catch (java.lang.UnsupportedOperationException e) {
System.err.println("UnsupportedOperationException : "+ e.getMessage() );
}
}
static void sleepThread( int sec ) {
try {
Thread.sleep( 1000 * sec );
} catch (InterruptedException e) {
e.printStackTrace();
}
}
«空鍵和空值
HashMap
允許最多一個空鍵和任意數量的空值。 由於Hashtable
甚至不允許單個空鍵和空值,如果鍵或值為空,則它會拋出 NullPointerException。 示例
«同步,線程安全
Hashtable
是內部同步的。 因此,在多線程應用中使用Hashtable
是非常安全的。 因為HashMap
不是內部同步的。 因此,在沒有外部同步的多線程應用中使用HashMap
是不安全的。 您可以使用Collections.synchronizedMap()
方法從外部同步HashMap
。
«性能
由於Hashtable
是內部同步的,這使得Hashtable
比HashMap
稍慢。
@見
對於線程應用程序,您通常可以使用 ConcurrentHashMap - 取決於您的性能要求。
1. Hashmap
和HashTable
都存儲 key 和 value。
2. Hashmap
可以存儲一個 key 為null
。 Hashtable
不能存儲null
。
3、 HashMap
不同步, Hashtable
同步。
HashMap
可以與Collection.SyncronizedMap(map)
同步
Map hashmap = new HashMap();
Map map = Collections.SyncronizedMap(hashmap);
除了已經提到的差異之外,需要注意的是,從 Java 8 開始, HashMap
將每個桶中使用的 Nodes(鏈表)動態替換為 TreeNodes(紅黑樹),這樣即使存在高哈希沖突,最壞的情況當搜索是
O(log(n)) for HashMap
Vs O(n) in Hashtable
。
*上述改進尚未應用於Hashtable
,而僅應用於HashMap
、 LinkedHashMap
和ConcurrentHashMap
。
僅供參考,目前,
TREEIFY_THRESHOLD = 8
:如果一個bucket包含8個以上的節點,則鏈表轉化為平衡樹。UNTREEIFY_THRESHOLD = 6
:當桶變得太小(由於移除或調整大小)時,樹將轉換回鏈表。HashTable 和 HashMaps 有 5 個基本區別。
我的小貢獻:
Hashtable
和HashMap
第一個也是最顯着的區別是,HashMap
不是線程安全的,而Hashtable
是線程安全的集合。
Hashtable
和HashMap
之間的第二個重要區別是性能,因為HashMap
不是同步的,它比Hashtable
性能更好。
Hashtable
與HashMap
第三個區別是Hashtable
是過時的類,您應該使用ConcurrentHashMap
代替 Java 中的Hashtable
。
HashMap:它是 java.util 包中可用的一個類,用於以鍵和值格式存儲元素。
Hashtable:它是一個遺留類,在集合框架內被識別。
Hashtable
是同步的,而HashMap
不是。HashMap
中的迭代器是故障安全的,而Hashtable
的枚舉器則不是。 如果您在迭代時更改地圖,您就會知道。HashMap
允許其中包含空值,而Hashtable
則不允許。HashTable是 jdk 中的遺留類,不應再使用。 用ConcurrentHashMap替換它的用法。 如果您不需要線程安全,請使用HashMap ,它不是線程安全的,但速度更快且使用更少的內存。
HashMap 和 HashTable
1) Hashtable 和 Hashmap 實現了 java.util.Map 接口 2) Hashmap 和 Hashtable 都是基於哈希的集合。 並致力於散列。 所以這些是HashMap和HashTable的相似之處。
1) 第一個區別是 HashMap 不是線程安全的,而 HashTable 是 ThreadSafe
2) HashMap 的性能更好,因為它不是線程安全的。 而 Hashtable 的性能並不好,因為它是線程安全的。 所以多個線程不能同時訪問Hashtable。
Hashtable:
哈希表是一種保留鍵值對值的數據結構。 它不允許鍵和值都為 null。 如果添加 null 值,您將收到NullPointerException
。 它是同步的。 所以它帶來了它的成本。 在特定時間只有一個線程可以訪問HashTable 。
示例:
import java.util.Map;
import java.util.Hashtable;
public class TestClass {
public static void main(String args[ ]) {
Map<Integer,String> states= new Hashtable<Integer,String>();
states.put(1, "INDIA");
states.put(2, "USA");
states.put(3, null); //will throw NullPointerEcxeption at runtime
System.out.println(states.get(1));
System.out.println(states.get(2));
// System.out.println(states.get(3));
}
}
哈希映射:
HashMap類似於Hashtable但它也接受鍵值對。 它允許鍵和值都為 null。 它的性能優於HashTable
,因為它是非unsynchronized
。
示例:
import java.util.HashMap;
import java.util.Map;
public class TestClass {
public static void main(String args[ ]) {
Map<Integer,String> states = new HashMap<Integer,String>();
states.put(1, "INDIA");
states.put(2, "USA");
states.put(3, null); // Okay
states.put(null,"UK");
System.out.println(states.get(1));
System.out.println(states.get(2));
System.out.println(states.get(3));
}
}
古老而經典的話題,只想添加這個有用的博客來解釋這一點:
http://blog.manishchhabra.com/2012/08/the-5-main-differences-betwen-hashmap-and-hashtable/
Manish Chhabra 的博客
HashMap 和 Hashtable 的 5 個主要區別
HashMap 和 Hashtable 都實現了 java.util.Map 接口,但 Java 開發人員必須了解一些差異才能編寫更高效的代碼。 從 Java 2 平台 v1.2 開始,對 Hashtable 類進行了改造以實現 Map 接口,使其成為 Java 集合框架的成員。
HashMap 和 Hashtable 的主要區別之一是 HashMap 是非同步的,而 Hashtable 是同步的,這意味着 Hashtable 是線程安全的,可以在多個線程之間共享,但 HashMap 不能在沒有適當同步的情況下在多個線程之間共享。 Java 5 引入了 ConcurrentHashMap,它是 Hashtable 的替代品,提供比 Java 中的 Hashtable 更好的可擴展性。同步意味着在一個時間點只有一個線程可以修改哈希表。 基本上,這意味着在對哈希表執行更新之前,任何線程都必須獲取對象上的鎖,而其他線程將等待釋放鎖。
HashMap 類大致等同於 Hashtable,除了它允許空值。 (HashMap 允許空值作為鍵和值,而 Hashtable 不允許空值)。
HashMap 與 Hashtable 之間的第三個顯着區別是 HashMap 中的 Iterator 是一個快速失敗的迭代器,而 Hashtable 的枚舉器不是,如果任何其他線程通過添加或刪除除迭代器自己的元素之外的任何元素在結構上修改映射,則拋出 ConcurrentModificationException ) 方法。 但這不是保證的行為,JVM 會盡最大努力完成。 這也是Java中Enumeration和Iterator的一個重要區別。
Hashtable 和 HashMap 之間更顯着的區別是,由於線程安全和同步,如果在單線程環境中使用,Hashtable 比 HashMap 慢得多。 因此,如果您不需要同步並且 HashMap 僅由一個線程使用,那么它在 Java 中執行 Hashtable。
HashMap 不保證映射的順序會隨着時間的推移保持不變。
請注意,HashMap 可以通過以下方式同步
Map m = Collections.synchronizedMap(hashMap);
總而言之,Java 中的 Hashtable 和 HashMap 之間存在顯着差異,例如線程安全和速度,並且僅在您絕對需要線程安全時才使用 Hashtable,如果您正在運行 Java 5,請考慮在 Java 中使用 ConcurrentHashMap。
HashMap
是模擬的,因此可以在GWT client code
使用,而Hashtable
則不是。
HashMaps使您可以自由進行同步,調試更加輕松
由於Java中的Hashtable是Dictionary類的子類,由於Map接口的存在,現在已經過時,不再使用。 此外,對於實現 Map Interface 的類,您可以使用 Hashtable 執行任何操作。
同步或線程安全 :
哈希映射未同步,因此不安全,並且在沒有適當的同步塊的情況下無法在多個線程之間共享,而哈希表已同步,因此是線程安全的。
空鍵和空值 :
HashMap允許一個null鍵和任意數量的null值。Hashtable不允許null鍵或值。
迭代值 :
HashMap中的Iterator是一個快速失敗的迭代器,而Hashtable的枚舉器則不是,如果其他線程通過添加或刪除Iterator自己的remove()方法之外的任何元素在結構上修改映射,則Hashtable的枚舉器將拋出ConcurrentModificationException。
超類和遺產 :
HashMap是AbstractMap類的子類,而Hashtable是Dictionary類的子類。
性能 :
由於HashMap不同步,因此與Hashtable相比,速度更快。
請參閱http://modernpathshala.com/Article/1020/difference-between-hashmap-and-hashtable-in-java中的示例以及與Java集合有關的訪談問題和測驗
HashMap 是一個用於以鍵和值格式存儲元素的類。它不是線程安全的。 因為它不是同步的。因為 Hashtable 是同步的。Hashmap 允許為空,但 hastable 不允許為空。
Hashtable 類是同步的,也就是說,它旨在供處理多線程或多線程進程的應用程序使用。 在應用程序到進程的經典情況下,同步類的效率較低,因此 Hashmap 類通常更快。 HashTable 類不接受 Null 值,無論是鍵還是值,而 HashMap 類允許單個鍵為 Null 並盡可能多地為 null。
Hashtable 是線程安全的,可以在應用程序中的多個線程之間共享。
另一方面,HashMap 不是同步的,如果沒有額外的同步代碼,就不能被多個線程訪問。 我們可以使用Collections.synchronizedMap()
來制作 HashMap 的線程安全版本。 我們也可以創建自定義鎖定代碼或使用 synchronized 關鍵字使代碼成為線程安全的。
HashMap 不是同步的,因此它比 Hashtable 更快並且使用更少的內存。 通常,在單線程應用程序中,未同步的對象比同步的對象要快。
Hashtable 根本不允許 null。
我們應該將 HashMap 用於非同步或單線程應用程序。
從 JDK 1.8 開始,Hashtable 已被棄用。 然而,ConcurrentHashMap 是一個很好的 Hashtable 替代品。 我們應該考慮在具有多線程的應用程序中使用 ConcurrentHashMap。
HashMap 和 Hashtable 將鍵/值對存儲在哈希表中。 使用 Hashtable 或 HashMap 時,我們指定一個用作鍵的對象以及要鏈接到該鍵的值。 然后對鍵進行散列,所得散列代碼用作將值存儲在表中的索引。 示例 Java 代碼。
// A sample Java program to demonstrate HashMap and HashTable
import java.util.*;
import java.lang.*;
import java.io.*;
// Name of the class has to be "Main" only if the class is public
class Ideone
{
public static void main(String args[])
{
// hashtable
Hashtable<Integer,String> ht=new Hashtable<Integer,String>();
ht.put(101," test");
ht.put(101,"test1");
ht.put(102,"test2");
ht.put(103,"test3");
System.out.println("-------------Hash table--------------");
for (Map.Entry m:ht.entrySet()) {
System.out.println(m.getKey()+" "+m.getValue());
}
// hashmap
HashMap<Integer,String> hm=new HashMap<Integer,String>();
hm.put(100,"test");
hm.put(104,"test1");
hm.put(101,"test2");
hm.put(102,"test3");
System.out.println("-----------Hash map-----------");
for (Map.Entry m:hm.entrySet()) {
System.out.println(m.getKey()+" "+m.getValue());
}
}
}
---- Hash table --- 103 test3 102 test2 101 test1
---- Hash map --- 100 test 101 test2 102 test3 104 test1
哈希圖與哈希表:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.