HashMap和Hashtable之间的区别?
Java中的a HashMap
和a有什么区别Hashtable
?
哪个非线程应用程序更有效?
回答
Java HashMap
和Hashtable
Java 之间存在一些差异:
由于同步不是你的问题,我建议HashMap
.如果同步成为问题,您也可以查看ConcurrentHashMap
.
- 我还要评论"Hashtable"中的线程安全的天真方法("同步每个方法应该处理任何并发问题!")使得线程应用程序非常糟糕*.你最好外部同步一个`HashMap`(并考虑后果),或使用`ConcurrentMap`实现(并利用其扩展API进行并发).结论:使用`Hashtable`的唯一原因是遗留API(来自大约1996年)需要它.
- 如果要使HashMap成为线程安全的,请使用`Collections.synchronizedMap()`.
- HashMap为程序员提供了在实际使用时编写threadSafe代码的灵活性.我很少需要一个像ConcurrentHashMap或HashTable这样的线程安全集合.我需要的是同步块中的某些函数或某些语句是线程安全的.
- Hashtable 已过时,我们将 HashMap 用于非线程安全环境。如果您需要线程安全,那么您可以使用 Collections.synchronizedMap() 或使用 ConcurrentHashMap ,它比哈希表更有效。
- 它已经过时但没有被弃用,我想知道为什么会这样。我猜想删除这个类(和 Vector 出于同样的原因)会破坏太多现有的代码,并且使用 @Deprecated 进行注释会暗示删除代码的意图,这显然不存在。
请注意,许多答案都表明Hashtable已同步. 在实践中,这很少给你买. 访问器/ mutator方法上的同步将停止两个线程同时添加或从地图中删除,但在现实世界中,您将经常需要额外的同步.
一个非常常见的习语是"检查然后放" - 即在地图中查找条目,如果它尚不存在则添加它.无论您使用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);
- 另请注意,如果修改了HashMap,则指向它的迭代器将变为无效.
- Iterator会抛出ConcurrentModificationException,对吧?
- 那么在线程安全方面,synchronized(myMap){...}和ConcurrentHashMap之间有什么区别吗?
- 非常的,我试着在这里解释一下..http://lovehasija.com/2012/08/16/who-said-java-hashtable-is-thread-safe/
Hashtable
被认为是遗留代码.没有什么Hashtable
可以使用HashMap
或推导无法完成HashMap
,所以对于新代码,我认为没有任何理由回到Hashtable
.
- 来自Hashtable javadoc(重点补充):"从Java 2平台v1.2开始,这个类被改进以实现Map接口,**使其成为Java Collections Framework**的成员." 但是,你是对的,它是遗留代码.使用Collections.synchronizedMap(HashMap)可以更有效地获得同步的所有好处.(类似于Vector是Collections.synchronizedList(ArrayList)的遗留版本.)
- @ aberrant80:遗憾的是你在两者之间别无选择,在为J2ME编程时必须使用Hashtable ...
- 这个答案应该删除.它包含不正确的信息,并有很多upvotes.
在访谈中经常会问这个问题,以检查候选人是否理解收集类的正确用法,并了解可用的替代解决方案.
- HashMap类大致相当于Hashtable,除了它是非同步的并且允许空值.(HashMap允许空值作为键和值,而Hashtable不允许空值).
- HashMap不保证地图的顺序会随着时间的推移保持不变.
- HashMap是非同步的,而Hashtable是同步的.
- HashMap中的迭代器是故障安全的,而Hashtable的枚举器不是,如果任何其他线程通过添加或删除除Iterator自己的remove()方法之外的任何元素来修改地图,则抛出ConcurrentModificationException.但这不是一种保证行为,将由JVM尽最大努力完成.
关于一些重要条款的说明
- 同步意味着只有一个线程可以在一个时间点修改哈希表.基本上,这意味着在哈希表上执行更新之前的任何线程都必须获取对象的锁定,而其他线程将等待锁定被释放.
- 故障安全与迭代器的上下文相关.如果已在集合对象上创建了迭代器,并且某个其他线程尝试"在结构上"修改集合对象,则将引发并发修改异常.其他线程可以调用"set"方法,因为它不会"在结构上"修改集合.但是,如果在调用"set"之前,集合已在结构上进行了修改,则会抛出"IllegalArgumentException".
- 结构修改意味着删除或插入可以有效改变地图结构的元素.
HashMap可以同步
HashMap
Map提供了Collection视图,而不是通过Enumeration对象直接支持迭代.集合视图极大地增强了界面的表现力,如本节后面所述.Map允许您迭代键,值或键值对; Hashtable不提供第三种选择.Map提供了一种在迭代过程中删除条目的安全方法; Hashtable没有.最后,Map修复了Hashtable界面中的一个小缺陷.Hashtable有一个名为contains的方法,如果Hashtable包含给定值,则返回true.鉴于其名称,如果Hashtable包含给定键,则您希望此方法返回true,因为该键是Hashtable的主要访问机制.Map接口通过重命名方法containsValue消除了这种混淆的来源.此外,这提高了界面的一致性 - containsValue parallels containsKey.
- 1)HashMap的迭代器不是故障安全的.他们失败快.这两个术语之间的含义存在巨大差异.2)`HashMap`上没有`set`操作.3)如果有先前的更改,`put(...)`操作不会抛出`IllegalArgumentException`.4)如果更改映射,则会出现`HashMap`**的快速失败行为.5)*保证快速失败行为*.(如果进行并发修改,则不能保证`HashTable`的行为.实际行为是......不可预测的.)
- 6)`Hashtable`不保证地图元素的顺序也会随时间稳定.(你可能会混淆`Hashtable`和`LinkedHashMap`.)
- 这个答案包含至少2个重要的事实不准确.它当然不值得这么多赞成.
- 其他任何人都非常担心这些天学生们错误地认为收集集合的"同步版本"意味着您不必外部同步复合操作?我最喜欢的一个例子是`thing.set(thing.get()+ 1);`它经常以惊人的方式捕获新手,因为完全不受保护,特别是如果同步`get()`和`set()`方法.他们中的许多人都期待着魔力.
HashMap
:Map
使用哈希代码索引数组的接口的实现.
Hashtable
:嗨,1998年叫.他们想要回收他们的集合API.
说真的,你最好远离Hashtable
完全.对于单线程应用程序,您不需要额外的同步开销.对于高度并发的应用程序,偏执同步可能会导致饥饿,死锁或不必要的垃圾收集暂停.就像Tim Howland指出的那样,你可以ConcurrentHashMap
改用它.
请记住,HashTable
在引入Java Collections Framework(JCF)之前,这是遗留类,后来为了实现Map
接口而进行了改进.那是Vector
和Stack
.
因此,总是在新代码中远离它们,因为在JCF中总有更好的替代方案,正如其他人所指出的那样.
这是您将发现有用的Java集合备忘单.请注意,灰色块包含遗留类HashTable,Vector和Stack.
已发布许多好的答案.我添加了一些新的点并总结了它.
HashMap
和Hashtable
两个用于存储在键和值形式的数据.两者都使用散列技术来存储唯一键.但是下面给出了HashMap和Hashtable类之间的许多差异.
HashMap中
-
HashMap
是非同步的.它不是线程安全的,如果没有适当的同步代码,就无法在许多线程之间共享. -
HashMap
允许一个空键和多个空值. -
HashMap
是JDK 1.2中引入的新类. -
HashMap
很快 - 我们可以
HashMap
通过调用此代码使其同步Map m = Collections.synchronizedMap(HashMap);
-
HashMap
由Iterator遍历. - 迭代器
HashMap
是快速失败的. -
HashMap
继承AbstractMap类.
哈希表
-
Hashtable
是同步的.它是线程安全的,可以与许多线程共享. -
Hashtable
不允许任何null键或值. -
Hashtable
是一个遗产类. -
Hashtable
是慢的. -
Hashtable
是内部同步的,不能不同步. -
Hashtable
由Enumerator和Iterator遍历. - 枚举器输入
Hashtable
不是快速失败的. -
Hashtable
继承Dictionary类.
进一步阅读Java中的HashMap和Hashtable有什么区别?
- @IgorGanapolsky你可能会读到这个 - http://stackoverflow.com/questions/21086307/what-are-the-legacy-classes-in-java/21086364#21086364
除了izb所说的,HashMap
允许空值,而Hashtable
不是.
另请注意,Hashtable
扩展Dictionary
该类(作为Javadocs状态)已过时并已被Map
接口替换.
- 但这不会使HashTable过时吗?
看看这张图表.它提供了不同数据结构与HashMap和Hashtable之间的比较.比较准确,清晰,易于理解.
Java Collection Matrix
Hashtable
类似于HashMap
并具有类似的界面.HashMap
除非您需要支持旧应用程序或需要同步,否则建议您使用,因为Hashtables
方法是同步的.因此,在您的情况下,因为您不是多线程,HashMaps
所以最好的选择.
散列表和散列映射之间的另一个关键区别是HashMap中的Iterator是快速失败的,而Hashtable的枚举器不是,如果任何其他Thread通过添加或删除除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中,我们还承诺能够构建和访问HashMaps,就像在旧的脚本语言中一样:
Map<String,Integer> map = { "orange" : 12, "apples" : 15 };
map["apples"];
更新:不,他们不会降落在1.8 ...... 🙁
Project Coin的集合增强功能将在JDK8中进行吗?
-
Map m = Collections.synchronizedMap(new HashMap(...));
HashMap
并且Hashtable
具有显着的算法差异.之前没有人提到这一点,所以这就是我提出这个问题的原因.HashMap
将构造一个具有两个大小的哈希表,动态增加它,使得你在任何桶中最多有八个元素(冲突),并且会很好地激发一般元素类型的元素.但是,Hashtable
如果你知道自己在做什么,那么实现提供了对哈希的更好和更精细的控制,即你可以使用最接近的质数来修复表大小到你的值域大小,这将导致比HashMap更好的性能,即更少的冲突对于某些情况.
除了在这个问题中广泛讨论的显而易见的差异之外,我认为Hashtable是一个"手动驱动"汽车,你可以更好地控制散列和HashMap作为通常表现良好的"自动驱动"对应物.
Hashtable是同步的,而HashMap则不是.这使得Hashtable比Hashmap慢.
对于非线程应用程序,请使用HashMap,因为它们在功能方面是相同的.
根据这里的信息,我建议使用HashMap.我认为最大的优点是Java会阻止你在迭代它时修改它,除非你通过迭代器完成它.
- 它实际上并没有阻止它,只是检测它并抛出错误.
A Collection
- 有时称为容器 - 只是一个将多个元素组合成一个单元的对象.Collection
s用于存储,检索,操作和传递聚合数据.集合框架W是用于表示和操作集合的统一体系结构.
的HashMap
JDK1.2
和Hashtable JDK1.0
,两者都用来表示一组在表示的对象的<Key, Value>
一对.每<Key, Value>
对称为Entry
对象.参赛作品的收集是由对象简称HashMap
和Hashtable
.集合中的键必须是唯一的或独特的.[因为它们用于检索特定键的映射值.集合中的值可以重复.]
« 超类,遗产和收藏框架成员
Hashtable是一个引入的遗留类JDK1.0
,它是Dictionary类的子类.从JDK1.2
Hashtable重新设计实现Map接口以构成集合框架的成员.HashMap从一开始就是Java Collection Framework的成员JDK1.2
.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 forHashMap
if hash bucket超过某个阈值,该桶将从中切换linked list of entries to a balanced tree
.它改善了从O(n)到O(log n)的最坏情况性能.在将列表转换为二叉树时,哈希码用作分支变量.如果同一个存储桶中有两个不同的哈希码,则一个被认为更大,并且位于树的右侧,另一个位于左侧.但是当两个哈希码都相等时,HashMap
假设密钥是可比较的,并比较密钥以确定方向,以便可以维持某个顺序.制作HashMap
可比较的钥匙是一个好习惯.在添加条目时,如果存储桶大小达到TREEIFY_THRESHOLD = 8
将条目的链接列表转换为平衡树,则在删除小于TREEIFY_THRESHOLD
和最多的条目时,UNTREEIFY_THRESHOLD = 6
会将平衡树重新转换为链接的条目列表.Java 8 SRC,stackpost
« 集合视图迭代,失败快速和失败安全
+--------------------+-----------+-------------+
| | Iterator | Enumeration |
+--------------------+-----------+-------------+
| Hashtable | fail-fast | safe |
+--------------------+-----------+-------------+
| HashMap | fail-fast | fail-fast |
+--------------------+-----------+-------------+
| ConcurrentHashMap | safe | safe |
+--------------------+-----------+-------------+
Iterator
是一种快速失败的性质.即如果在迭代时修改集合而不是它自己的remove()方法,则抛出ConcurrentModificationException.凡为Enumeration
是故障安全性的.如果在迭代时修改了集合,则不会抛出任何异常.
根据Java API Docs,Iterator始终优于Enumeration.
注意: Enteration接口的功能由Iterator接口复制.此外,Iterator添加了一个可选的删除操作,并且具有更短的方法名称.新实现应考虑使用Iterator而不是Enumeration.
在Java 5中引入了ConcurrentMap接口:ConcurrentHashMap
- ConcurrentMap
由哈希表支持的高度并发,高性能的实现.执行检索时,此实现永远不会阻塞,并允许客户端选择更新的并发级别.它旨在作为以下内容的替代品Hashtable
:除了实现之外ConcurrentMap
,它还支持所有特有的"遗留"方法Hashtable
.
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
不允许甚至单个null键和null值,如果键或值为null,则抛出NullPointerException.例
« 同步,线程安全
Hashtable
在内部同步.因此,Hashtable
在多线程应用程序中使用它是非常安全的.哪里HashMap
没有内部同步.因此,HashMap
在没有外部同步的多线程应用程序中使用是不安全的.您可以HashMap
使用Collections.synchronizedMap()
方法在外部进行同步.
« 表现
由于Hashtable
在内部同步,这Hashtable
比稍微慢一点HashMap
.
@看到
- 红黑树是一种自平衡二叉搜索树
-
HashMap
Java 8中的性能改进
对于线程应用程序,您可以经常使用ConcurrentHashMap - 取决于您的性能要求.
1. Hashmap
并HashTable
存储密钥和值.
2. Hashmap
可以存储一个密钥null
.Hashtable
不能存储null
.
3. HashMap
未同步但Hashtable
已同步.
4. HashMap
可以同步Collection.SyncronizedMap(map)
Map hashmap = new HashMap();
Map map = Collections.SyncronizedMap(hashmap);
除了已经提到的差异,应该指出的是,自从Java 8,HashMap
动态替换每个桶使用树节点(红黑树)的节点(链表),这样,即使高哈希冲突存在,最坏的情况下,当搜索是
O(log(n))对于HashMap
Vs O(n)in Hashtable
.
*上述改进还没有被应用到Hashtable
还没有,但只HashMap
,LinkedHashMap
和ConcurrentHashMap
.
仅供参考,目前,
-
TREEIFY_THRESHOLD = 8
:如果存储桶包含8个以上的节点,则链表将转换为平衡树. -
UNTREEIFY_THRESHOLD = 6
:当桶变得太小(由于删除或调整大小)时,树将转换回链表.
HashTable和HashMaps有5个基本区别.
- Maps允许您迭代和检索键,值和两个键值对,其中HashTable没有所有这些功能.
- 在Hashtable中有一个函数contains(),它使用起来非常混乱.因为contains的含义略有偏差.它意味着包含密钥还是包含值?难以理解.在Maps中我们有ContainsKey()和ContainsValue()函数,它们很容易理解.
- 在hashmap中,您可以安全地在迭代时删除元素.在哈希表中不可能的地方.
- HashTable默认是同步的,因此它可以轻松地与多个线程一起使用.默认情况下,HashMaps不同步,因此只能与单个线程一起使用.但您仍然可以使用Collections util类的synchronizedMap(Map m)函数将HashMap转换为同步.
- HashTable不允许使用null键或null值.HashMap允许一个空键和多个空值的位置.
我的小贡献:
HashMap:它是java.util包中可用的类,它用于以键和值格式存储元素.
Hashtable:它是一个遗留类,在集合框架中被识别.
- 你为什么重复已经给出的答案?
HashTable是jdk中的遗留类,不应再使用了.用ConcurrentHashMap替换它的用法.如果您不需要线程安全,请使用HashMap,它不是线程安全但更快并且使用更少的内存.
HashMap和Hashtable都用于以键值形式存储数据。两者都使用散列技术来存储唯一键。下面给出了 HashMap 和 Hashtable 类之间的许多差异。
1)Hashtable是同步的,而hashmap不是.2)另一个区别是HashMap中的迭代器是故障安全的,而Hashtable的枚举器则不是.如果你在迭代时更改地图,你就会知道.
3)HashMap允许空值,而Hashtable则不允许.
- HashMap迭代器是快速失败的,不是故障安全的.这就是为什么我们有ConcurrentHashMap允许迭代修改.查看这篇文章http://www.journaldev.com/122/hashmap-vs-concurrenthashmap-%e2%80%93-example-and-exploring-iterator
- 你为什么重复已经给出的答案?
HashMap和HashTable
- 关于HashMap和HashTable的一些重要观点.请阅读以下详细信息.
1)Hashtable和Hashmap实现java.util.Map接口2)Hashmap和Hashtable都是基于散列的集合.并致力于散列.所以这些是HashMap和HashTable的相似之处.
- HashMap和HashTable有什么区别?
1)第一个区别是HashMap不是线程安全的,而HashTable是ThreadSafe
2)HashMap更好,因为它不是线程安全的.虽然Hashtable性能明智并不好,因为它是线程安全的.所以多线程不能同时访问Hashtable.
- 投反对票,因为这个答案在某些方面不正确。Hashtable 没有实现 Map 接口,只是扩展了已经过时的 Dictionary 类。
Hashtable:
Hashtable是一种保留键值对值的数据结构.它不允许键和值都为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的:
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 都实现了 java.util.Map 接口,但 Java 开发人员必须了解一些差异才能编写更高效的代码。从 Java 2 平台 v1.2 开始,对 Hashtable 类进行了改造以实现 Map 接口,使其成为 Java Collections Framework 的成员。
请注意,HashMap 可以通过以下方式同步
Map m = Collections.synchronizedMap(hashMap);
总而言之,Java 中的 Hashtable 和 HashMap 之间存在显着差异,例如线程安全和速度,并且仅在您绝对需要线程安全时才使用 Hashtable,如果您正在运行 Java 5,请考虑在 Java 中使用 ConcurrentHashMap。
HashMap
被模拟,因此可用于GWT client code
而Hashtable
不是。
同步或线程安全:
Hash Map 不是同步的,因此它不是线程安全的,并且它不能在没有适当的同步块的情况下在多个线程之间共享,而 Hashtable 是同步的,因此它是线程安全的。
空键和空值:
HashMap 允许一个空键和任意数量的空值。Hashtable 不允许空键或值。
迭代值:
HashMap 中的迭代器是一个快速失败的迭代器,而 Hashtable 的枚举器不是,如果任何其他线程通过添加或删除除迭代器自己的 remove() 方法之外的任何元素在结构上修改映射,则抛出 ConcurrentModificationException 。
超类和遗产:
HashMap 是 AbstractMap 类的子类,而 Hashtable 是 Dictionary 类的子类。
性能:
由于 HashMap 不是同步的,它比 Hashtable 更快。
请参阅http://modernpathshala.com/Article/1020/difference-between-hashmap-and-hashtable-in-java以获取与 Java 集合相关的示例和面试问题和测验