Java中的aHashMap
和a有什么区别?Hashtable
哪个对非线程应用程序更有效?
HashMap
Java之间和Java之间有几个区别Hashtable
:
Hashtable
是同步的,而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");
}
即使迭代 aHashtable
的条目(或由HashMap
获得的a Collections.synchronizedMap
)也不是线程安全的,除非您还Map
通过额外的同步来防止被修改。
接口的实现ConcurrentMap
(例如ConcurrentHashMap
)通过包含线程安全的 check-then-act 语义来解决其中的一些问题,例如:
ConcurrentMap.putIfAbsent(key, value);
Hashtable
被认为是遗留代码。没有什么Hashtable
不能使用HashMap
或派生来完成的HashMap
,所以对于新代码,我看不出有任何理由回到Hashtable
.
这个问题经常在面试中被问到,以检查候选人是否理解集合类的正确用法以及是否知道可用的替代解决方案。
HashMap
大致相当于Hashtable
,除了它是非同步的并且允许空值。(HashMap
允许空值作为键和值,而Hashtable
不允许null
s)。HashMap
不保证地图的顺序会随着时间的推移保持不变。HashMap
是非同步的,Hashtable
而是同步的。HashMap
是故障安全的,而枚举Hashtable
器不是,并且ConcurrentModificationException
如果任何其他线程通过添加或删除除Iterator
自己的remove()
方法之外的任何元素来在结构上修改映射,则抛出异常。但这不是保证行为,JVM 会尽最大努力来完成。一些重要术语的注意事项:
Hashtable
都必须获取对象上的锁,而其他线程将等待锁被释放。set
方法,因为它不会“结构地”修改集合。但是,如果在调用之前set
,集合已经在结构上进行了修改,IllegalArgumentException
则会被抛出。HashMap
可以通过同步
Map m = Collections.synchronizeMap(hashMap);
Map 提供 Collection 视图,而不是通过 Enumeration 对象直接支持迭代。集合视图极大地增强了界面的表现力,这将在本节后面讨论。Map 允许您迭代键、值或键值对;Hashtable
不提供第三种选择。Map 提供了一种在迭代过程中删除条目的安全方法;Hashtable
没有。Hashtable
最后,Map 修复了界面中的一个小缺陷。Hashtable
有一个名为 contains 的方法,如果Hashtable
包含给定值,则返回 true。鉴于它的名称,如果包含给定的键,您会期望此方法返回 true,Hashtable
因为该键是 a 的主要访问机制Hashtable
。Map 接口通过重命名方法消除了这种混淆来源containsValue
. 此外,这提高了界面的一致性containsValue
——parallels containsKey
。
HashMap
:Map
使用哈希码索引数组的接口实现。
Hashtable
: 你好,1998 年打来的。他们希望他们的收藏 API 回来。
不过说真的,你最好完全远离Hashtable
。对于单线程应用程序,您不需要额外的同步开销。对于高度并发的应用程序,偏执的同步可能会导致饥饿、死锁或不必要的垃圾收集暂停。就像 Tim Howland 指出的那样,您可以ConcurrentHashMap
改用。
请记住,HashTable
在引入 Java 集合框架 (JCF) 之前,它是遗留类,后来被改造以实现Map
接口。Vector
和 也是如此Stack
。
因此,在新代码中始终远离它们,因为正如其他人所指出的那样,JCF 中总是有更好的选择。
这是您会发现有用的Java 集合备忘单。请注意,灰色块包含遗留类 HashTable、Vector 和 Stack。
已经发布了许多好的答案。我正在添加一些新观点并对其进行总结。
HashMap
并且Hashtable
两者都用于以键和值形式存储数据。两者都使用散列技术来存储唯一键。但是下面给出的 HashMap 和 Hashtable 类之间存在许多差异。
哈希映射
HashMap
是非同步的。它不是线程安全的,如果没有适当的同步代码,就不能在多个线程之间共享。HashMap
允许一个空键和多个空值。HashMap
是 JDK 1.2 中引入的一个新类。HashMap
很快。HashMap
as 同步Map m = Collections.synchronizedMap(HashMap);
HashMap
被迭代器遍历。HashMap
是快速失败的。HashMap
继承 AbstractMap 类。哈希表
Hashtable
是同步的。它是线程安全的,可以与许多线程共享。Hashtable
不允许空键或值。Hashtable
是一个遗留类。Hashtable
是缓慢的。Hashtable
是内部同步的,不能不同步。Hashtable
由 Enumerator 和 Iterator 遍历。Hashtable
器不是快速失败的。Hashtable
继承字典类。看看这张图表。HashMap
它与和一起提供了不同数据结构之间的比较Hashtable
。比较准确、清晰且易于理解。
除了 izb 所说的,HashMap
允许空值,而Hashtable
不允许。
另请注意,作为JavadocsHashtable
状态的扩展Dictionary
类已过时,已被接口取代。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,那么它必须在外部同步。您可以使用以下方法将未同步的地图包装在同步地图中:
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 的哈希表,动态增加它,这样您在任何桶中最多有大约八个元素(碰撞),并且对于一般元素类型会很好地搅拌元素。但是,Hashtable
如果您知道自己在做什么,则该实现提供了对散列的更好和更精细的控制,即您可以使用最接近您的值域大小的素数来修复表大小,这将导致比 HashMap 更好的性能,即更少的冲突对于某些情况。
与此问题中广泛讨论的明显差异不同,我将 Hashtable 视为“手动驾驶”汽车,您可以更好地控制散列,而 HashMap 作为“自动驾驶”对应物,通常会表现良好。
根据此处的信息,我建议使用 HashMap。我认为最大的优势是 Java 会阻止您在迭代它时对其进行修改,除非您通过迭代器进行修改。
A Collection
(有时称为容器)只是将多个元素组合成一个单元的对象。Collection
s 用于存储、检索、操作和通信聚合数据。集合框架W是用于表示和操作集合的统一架构。
和HashMap
JDK1.2
Hashtable JDK1.0
,都用于表示<Key, Value>
成对表示的一组对象。每<Key, Value>
对称为Entry
对象。Entries 的集合由 和 的对象HashMap
引用Hashtable
。集合中的键必须是唯一的或独特的。[因为它们用于检索特定键的映射值。集合中的值可以重复。]
« 超类、遗产和集合框架成员
Hashtable 是 中引入的遗留类JDK1.0
,是 Dictionary 类的子类。From JDK1.2
Hashtable 被重新设计以实现Map 接口,成为集合框架的成员。HashMap 是 Java 集合框架的成员,从它在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 开始,HashMap
如果哈希桶增长超过某个阈值,该桶将从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
« 集合视图迭代,Fail-Fast 和 Fail-Safe
+--------------------+-----------+-------------+
| | Iterator | Enumeration |
+--------------------+-----------+-------------+
| Hashtable | fail-fast | safe |
+--------------------+-----------+-------------+
| HashMap | fail-fast | fail-fast |
+--------------------+-----------+-------------+
| ConcurrentHashMap | safe | safe |
+--------------------+-----------+-------------+
Iterator
本质上是快速失败的。即,如果在迭代时修改了集合而不是它自己的 remove() 方法,它会抛出 ConcurrentModificationException。asEnumeration
本质上是故障安全的。如果在迭代时修改了集合,它不会抛出任何异常。
根据 Java API Docs,Iterator 总是优于 Enumeration。
注意:枚举接口的功能与迭代器接口相同。此外,Iterator 添加了一个可选的删除操作,并且具有更短的方法名称。新的实现应该考虑使用迭代器而不是枚举。
在Java 5 中引入了 ConcurrentMap 接口: -由哈希表支持ConcurrentHashMap
的高度并发、高性能的实现。ConcurrentMap
此实现在执行检索时从不阻塞,并允许客户端选择更新的并发级别。它旨在替代Hashtable
: 除了实现之外ConcurrentMap
,它还支持Hashtable
.
每个HashMapEntry
s 值都是易变的,从而确保竞争修改和后续读取的细粒度一致性;每次读取都反映了最近完成的更新
迭代器和枚举是故障安全的 - 反映自迭代器/枚举创建以来某个时刻的状态;这允许以降低一致性为代价同时读取和修改。它们不会抛出 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
最多允许一个空键和任意数量的空值。asHashtable
甚至不允许单个空键和空值,如果键或值为空,则抛出 NullPointerException。例子
« 同步,线程安全
Hashtable
是内部同步的。Hashtable
因此,在多线程应用程序中使用是非常安全的。其中 asHashMap
不是内部同步的。HashMap
因此,在没有外部同步的情况下在多线程应用程序中使用是不安全的。HashMap
您可以使用Collections.synchronizedMap()
方法进行外部同步。
« 性能
由于Hashtable
是内部同步的,这Hashtable
比HashMap
.
@看
对于线程应用程序,您通常可以使用 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
将每个桶中使用的 Nodes(链表)动态替换为 TreeNodes(红黑树),这样即使存在高哈希冲突,最坏的情况是搜索是
O(log(n)) 对于HashMap
Vs O(n) in Hashtable
。
*上述改进尚未应用于Hashtable
, HashMap
,LinkedHashMap
和ConcurrentHashMap
.
仅供参考,目前,
TREEIFY_THRESHOLD = 8
:如果一个桶包含超过8个节点,则将链表转换为平衡树。UNTREEIFY_THRESHOLD = 6
:当桶变得太小(由于删除或调整大小)时,树将转换回链表。HashTable 和 HashMap 有 5 个基本区别。
HashMap:它是 java.util 包中的一个类,用于以键值格式存储元素。
Hashtable:它是一个在集合框架中被识别的遗留类。
我的小贡献:
和之间的第一个也是最重要的区别是,
Hashtable
不是线程安全的,而是线程安全的集合。HashMap
HashMap
Hashtable
Hashtable
和之间的第二个重要区别HashMap
是性能,因为HashMap
不同步它的性能优于Hashtable
.
Hashtable
vs的第三个区别HashMap
是它Hashtable
是过时的类,你应该在 Java 中使用ConcurrentHashMap
它Hashtable
。
Hashtable
是同步的,而HashMap
不是同步的。HashMap
是故障安全的,而 enumeratorHashtable
则不是。如果您在迭代时更改地图,您就会知道。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:
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类似于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));
}
}
由于 Java 中的 Hashtable 是 Dictionary 类的子类,由于 Map Interface 的存在,现在已经过时,因此不再使用它。此外,对于实现 Map 接口的类,没有什么是您不能用 Hashtable 做的。
古老而经典的话题,只想添加这个有用的博客来解释这一点:
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 Collections Framework 的成员。
HashMap 和 Hashtable 之间的主要区别之一是 HashMap 是非同步的,而 Hashtable 是同步的,这意味着 Hashtable 是线程安全的,可以在多个线程之间共享,但 HashMap 不能在没有适当同步的情况下在多个线程之间共享。Java 5 引入了 ConcurrentHashMap,它是 Hashtable 的替代品,提供了比 Java 中的 Hashtable 更好的可扩展性。同步意味着在一个时间点只有一个线程可以修改一个哈希表。基本上,这意味着任何线程在对哈希表执行更新之前都必须获取对象上的锁,而其他线程将等待锁被释放。
HashMap 类大致相当于 Hashtable,除了它允许空值。(HashMap 允许空值作为键和值,而 Hashtable 不允许空值)。
HashMap 与 Hashtable 之间的第三个重要区别是 HashMap 中的 Iterator 是一个快速失败的迭代器,而 Hashtable 的枚举器不是,并且如果任何其他线程通过添加或删除除 Iterator 自己的 remove( ) 方法。但这不是保证行为,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。
同步或线程安全:
Hash Map 不是同步的,因此它不是线程安全的,并且如果没有适当的同步块,它就不能在多个线程之间共享,而 Hashtable 是同步的,因此它是线程安全的。
空键和空值:
HashMap 允许一个空键和任意数量的空值。Hashtable 不允许空键或空值。
迭代值:
HashMap 中的迭代器是一个快速失败的迭代器,而 Hashtable 的枚举器不是,如果任何其他线程通过添加或删除除 Iterator 自己的 remove() 方法之外的任何元素在结构上修改映射,则抛出 ConcurrentModificationException。
超类和遗产:
HashMap 是 AbstractMap 类的子类,而 Hashtable 是 Dictionary 类的子类。
性能:
由于 HashMap 不同步,因此它比 Hashtable 更快。
请参阅http://modernpathshala.com/Article/1020/difference-between-hashmap-and-hashtable-in-java以获取与 Java 集合相关的示例和面试问题和测验
HashMap
是模拟的,因此可用于GWT client code
而Hashtable
不是。
HashMaps 让您可以自由同步,调试更容易
HashMap 是一个用于以键值格式存储元素的类。它不是线程安全的。因为它不是同步的 .where 因为 Hashtable 是同步的。Hashmap 允许 null 但 hastable 不允许 null。
Hashtable 类是同步的,也就是说,它旨在供处理多线程或多线程进程的应用程序使用。在将应用程序应用于进程的经典情况下,同步类的效率较低,因此 Hashmap 类通常更快。HashTable 类不接受 Null 值,无论是键还是值,而 HashMap 类允许单个键具有 Null 和尽可能多的 null。