提问人:dmanxiii 提问时间:9/3/2008 最后编辑:Steve Chambersdmanxiii 更新时间:10/1/2023 访问量:1733979
Java 中的 HashMap 和 Hashtable 有什么区别?
What are the differences between a HashMap and a Hashtable in Java?
答:
根据这里的信息,我建议使用 HashMap。我认为最大的优点是 Java 会阻止你在迭代它时修改它,除非你通过迭代器来修改它。
评论
Hashtable
是同步的,而不是。这使得比 .HashMap
Hashtable
Hashmap
对于单线程应用程序,请使用,因为它们在功能方面是相同的。HashMap
Hashtable
类似于 和 具有类似的接口。建议使用 ,除非您需要支持旧版应用程序或需要同步,因为这些方法是同步的。因此,就您而言,由于您不是多线程,因此是您最好的选择。HashMap
HashMap
Hashtables
HashMaps
除了 izb 所说的之外,还允许 null 值,而 不允许。HashMap
Hashtable
另请注意,扩展类,作为 Javadocs 状态,该类已过时,已被接口替换。Hashtable
Dictionary
Map
对于线程应用,通常可以使用 ConcurrentHashMap,具体取决于性能要求。
Java 中的 HashMap
和 Hashtable
之间有几个区别:
Hashtable
是同步的,而不是。这更适合非线程应用程序,因为未同步的对象通常比同步的对象性能更好。HashMap
HashMap
Hashtable
不允许键或值。 允许一个键和任意数量的值。null
HashMap
null
null
HashMap 的一个子类是
LinkedHashMap
,因此,如果您想要可预测的迭代顺序(默认情况下是插入顺序),您可以轻松地将 .如果您使用 .HashMap
LinkedHashMap
Hashtable
由于同步对您来说不是问题,因此我建议 .如果同步成为一个问题,您还可以查看 ConcurrentHashMap
。HashMap
评论
Collections.synchronizedMap()
Hashtable
HashMap
ConcurrentMap
Hashtable
HashMap
:使用哈希代码为数组编制索引的接口的实现。: 嗨,1998 年打来的电话。他们希望恢复其集合 API。Map
Hashtable
不过说真的,你最好完全远离。对于单线程应用,不需要额外的同步开销。对于高度并发的应用,偏执同步可能会导致饥饿、死锁或不必要的垃圾回收暂停。正如 Tim Howland 指出的那样,您可以改用。Hashtable
ConcurrentHashMap
评论
请注意,很多答案都指出 Hashtable 是同步的。在实践中,这给你带来的很少。同步在访问器/赋值器方法上将停止两个线程同时在映射中添加或删除,但在现实世界中,您通常需要额外的同步。
一个非常常见的成语是“检查然后放置”——即在 中查找一个条目,如果它不存在,则添加它。这绝不是原子操作,无论您使用 或 .Map
Hashtable
HashMap
等效同步可以通过以下方式获得:HashMap
Collections.synchronizedMap(myMap);
但是要正确实现此逻辑,您需要对表单进行额外的同步:
synchronized(myMap) {
if (!myMap.containsKey("tomato"))
myMap.put("tomato", "red");
}
即使遍历 a 的条目(或由 获取的条目)也不是线程安全的,除非您还防止通过额外的同步进行修改。Hashtable
HashMap
Collections.synchronizedMap
Map
ConcurrentMap
接口的实现(例如 ConcurrentHashMap
)通过包含线程安全的 check-then-act 语义来解决其中的一些问题,例如:
ConcurrentMap.putIfAbsent(key, value);
评论
Hashtable
被视为遗留代码。没有什么是不能使用或派生的,所以对于新代码,我看不出有任何理由回到 。Hashtable
HashMap
HashMap
Hashtable
评论
和之间的另一个关键区别是,HashMap 中的迭代器是快速失败的,而 Hashtable 的枚举器不是,如果任何其他线程通过添加或删除除迭代器自己的 remove() 方法之外的任何元素在结构上修改映射,则抛出 ConcurrentModificationException。但这不是一个有保证的行为,JVM将尽最大努力完成。Hashtable
HashMap
我的消息来源:http://javarevisited.blogspot.com/2010/10/difference-between-hashmap-and.html
这个问题经常在面试中被问到,以检查候选人是否理解集合类的正确用法,并了解可用的替代解决方案。
- 该类大致等同于 ,只是它是非同步的,并且允许 null。(允许 null 值作为键和值,而不允许 s)。
HashMap
Hashtable
HashMap
Hashtable
null
HashMap
不保证地图的顺序随时间推移保持不变。HashMap
是非同步的,而是同步的。Hashtable
- 中的迭代器是故障安全的,而 的枚举器不是,如果任何其他线程通过添加或删除除自己的方法之外的任何元素在结构上修改映射,则抛出。但这不是一个有保证的行为,JVM将尽最大努力完成。
HashMap
Hashtable
ConcurrentModificationException
Iterator
remove()
关于一些重要术语的说明:
- 同步意味着在一个时间点只有一个线程可以修改哈希表。基本上,这意味着在对对象执行更新之前,任何线程都必须获取对象的锁,而其他线程将等待锁被释放。
Hashtable
- 故障安全与迭代器的上下文相关。如果在集合对象上创建了迭代器,并且其他线程尝试“结构化”修改集合对象,则将引发并发修改异常。不过,其他线程也可以调用该方法,因为它不会“结构化地”修改集合。但是,如果在调用之前,集合在结构上已经修改过,则会抛出。
set
set
IllegalArgumentException
- 结构修改是指删除或插入可以有效改变地图结构的元素。
HashMap
可以通过以下方式进行同步
Map m = Collections.synchronizeMap(hashMap);
Map 提供 Collection 视图,而不是直接支持通过 Enumeration 对象进行迭代。集合视图极大地增强了界面的表现力,如本节后面所述。Map 允许您遍历键、值或键值对; 不提供第三种选择。Map 提供了一种在迭代过程中删除条目的安全方法; 冇。最后,Map 修复了界面中的一个小缺陷。 有一个名为 contains 的方法,如果包含给定值,则返回 true。给定其名称,如果包含给定的键,则此方法将返回 true,因为该键是 .Map 接口通过重命名方法 来消除这种混淆的根源。此外,这提高了接口的一致性 — parallels .Hashtable
Hashtable
Hashtable
Hashtable
Hashtable
Hashtable
Hashtable
containsValue
containsValue
containsKey
评论
set
HashMap
put(...)
IllegalArgumentException
HashMap
HashTable
Hashtable
Hashtable
LinkedHashMap
thing.set(thing.get() + 1);
get()
set()
除了这里已经提到的所有其他重要方面之外,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 中吗?
评论
Hashtable
Map
Iterable
Hashtable.keySet()
Set
Map
HashTable 是同步的,如果你在单个线程中使用它,你可以使用 HashMap,这是一个不同步的版本。不同步对象的性能通常更高一些。顺便说一句,如果多个线程同时访问一个 HashMap,并且至少有一个线程在结构上修改了 map,则必须在外部同步。 Youn 可以使用以下命令将未同步的地图包装在同步的地图中:
Map m = Collections.synchronizedMap(new HashMap(...));
HashTable 只能包含非 null 对象作为键或值。HashMap 可以包含一个 null 键和 null 值。
Map 返回的迭代器是快速失败的,如果在创建迭代器后的任何时候对 Map 进行结构修改,除了通过迭代器自己的 remove 方法之外,迭代器将抛出一个 .因此,在面对并发修改时,迭代器会快速而干净地失败,而不是冒着在未来不确定时间出现任意、非确定性行为的风险。而 Hashtable 的键和元素方法返回的枚举不是快速失败的。
ConcurrentModificationException
HashTable 和 HashMap 是 Java 集合框架的成员(从 Java 2 平台 v1.2 开始,HashTable 被改造为实现 Map 接口)。
HashTable 被认为是遗留代码,如果需要线程安全的高并发实现,文档建议使用 ConcurrentHashMap 代替 Hashtable。
HashMap 不保证返回元素的顺序。对于 HashTable,我想它是一样的,但我不完全确定,我没有找到明确说明这一点的资源。
HashMaps为您提供了同步的自由,调试变得更加容易
请看这张图表。它提供了不同数据结构以及 和 之间的比较。比较准确、清晰、易于理解。HashMap
Hashtable
HashMap
并且还具有显着的算法差异。以前没有人提到过这一点,所以这就是我提出它的原因。 将构造一个幂为两个大小的哈希表,动态增加它,使得任何存储桶中最多有大约八个元素(碰撞),并且对于一般元素类型,这些元素会很好地搅拌元素。但是,如果您知道自己在做什么,则该实现可以更好、更精细地控制哈希,即您可以使用最接近您的值域大小的素数来修复表大小,这将导致比 HashMap 更好的性能,即在某些情况下更少的冲突。Hashtable
HashMap
Hashtable
除了这个问题中广泛讨论的明显差异之外,我认为 Hashtable 是一辆“手动驾驶”汽车,您可以在其中更好地控制哈希,而 HashMap 是“自动驾驶”对应物,通常性能良好。
Hashtable
是同步的,而不是。HashMap
- 另一个区别是迭代器是故障安全的
而 IS 的枚举器则不是。如果更改地图
在迭代时,您就会知道。
HashMap
Hashtable
HashMap
允许其中的 null 值,而不允许。Hashtable
评论
HashMap:它是 java.util 包中可用的类,用于以键和值格式存储元素。
哈希表:它是一个遗留类,在集合框架中被识别。
HashTable 是 jdk 中的一个遗留类,不应再使用。将其用法替换为 ConcurrentHashMap。如果不需要线程安全,请使用 HashMap,它不是线程安全的,但速度更快,使用更少的内存。
评论
HashMap
是模拟的,因此可用于 而 不是。GWT client code
Hashtable
HashMap 是一个用于将元素存储在键和值中的类 format.it 它不是线程安全的。 因为它没有同步 .where as Hashtable 是同步的。Hashmap 允许 null,但 hastable 不允许 null。
HashTable 和 HashMaps 有 5 个基本区别。
- Maps 允许您迭代和检索键、值和两个键值对,而 HashTable 不具备所有这些功能。
- 在 Hashtable 中有一个函数 contains(),使用起来非常混乱。因为包含的含义略有偏差。它是否意味着包含键或包含值?很难理解。同样,在 Maps 中,我们有 ContainsKey() 和 ContainsValue() 函数,它们非常容易理解。
- 在哈希图中,您可以在迭代时安全地删除元素。因为在哈希表中是不可能的。
- 默认情况下,HashTables 是同步的,因此它可以很容易地与多个线程一起使用。其中,由于 HashMap 默认不同步,因此只能与单个线程一起使用。但是您仍然可以使用 Collections util 类的 synchronizedMap(Map m) 函数将 HashMap 转换为同步。
- HashTable 不允许 null 键或 null 值。其中 as HashMap 允许一个 null 键和多个 null 值。
由于 Java 中的 Hashtable 是 Dictionary 类的子类,由于 Map Interface 的存在,它现在已经过时了,因此不再使用。此外,对于实现 Map Interface 的类,没有什么是不能用 Hashtable 做的。
我的小贡献:
和之间的第一个也是最显着的区别是,它不是线程安全的,而是一个线程安全的集合。
Hashtable
HashMap
HashMap
Hashtable
和之间的第二个重要区别是性能,因为不同步,它的性能比 好。
Hashtable
HashMap
HashMap
Hashtable
vs 的第三个区别是它是过时的类,您应该在 Java 中使用 代替。
Hashtable
HashMap
Hashtable
ConcurrentHashMap
Hashtable
请记住,在引入 Java 集合框架 (JCF) 之前,它是遗留类,后来经过改造以实现该接口。所以是和.HashTable
Map
Vector
Stack
因此,在新代码中始终远离它们,因为正如其他人指出的那样,JCF 中总是有更好的替代方案。
这是 Java 集合备忘单,您会发现它很有用。请注意,灰色块包含旧类 HashTable、Vector 和 Stack。
HashMap 和 HashTable
- 关于 HashMap 和 HashTable 的一些要点。 请阅读以下详细信息。
1) Hashtable 和 Hashmap 实现 java.util.Map 接口 2) Hashmap 和 Hashtable 都是基于哈希的集合。并致力于散列。 所以这些是 HashMap 和 HashTable 的相似之处。
- HashMap 和 HashTable 有什么区别?
1) 第一个区别是 HashMap 不是线程安全的,而 HashTable 是线程安全的 2) HashMap 在性能方面更好,因为它不是线程安全的
。而 Hashtable 的性能并不好,因为它是线程安全的。所以多个线程不能同时访问 Hashtable。
评论
古老而经典的话题,只想添加这个有用的博客来解释这一点:
http://blog.manishchhabra.com/2012/08/the-5-main-differences-between-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 是同步的,这 意味着哈希表是线程安全的,可以在多个之间共享 线程,但 HashMap 不能在没有 正确的同步。Java 5 引入了 ConcurrentHashMap,它是 Hashtable 的替代方案,并提供比 Java.Synchronized 中的 Hashtable 意味着只有一个线程可以修改哈希 表。基本上,这意味着任何线程之前 在哈希表上执行更新必须获取 对象,而其他人将等待锁定被释放。
HashMap 类大致等同于 Hashtable,只不过它允许 null。(HashMap 允许 null 值作为键和值,而 Hashtable 不允许 null)。
HashMap 与 Hashtable 之间的第三个显着区别是 HashMap 中的迭代器是一个快速失败的迭代器,而 Hashtable 的枚举器 is not 和 throw ConcurrentModificationException,如果任何其他线程修改映射 在结构上,通过添加或删除除迭代器自己的元素之外的任何元素 remove() 方法。但这不是一种有保证的行为,并且会 由 JVM 尽最大努力完成。这也是一个重要的区别 在 Java 中的枚举和迭代器之间。
Hashtable 和 HashMap 之间另一个值得注意的区别是,由于线程安全和同步,Hashtable 要慢得多 如果在单线程环境中使用,则比 HashMap 。所以如果你不这样做 需要同步,而 HashMap 仅由一个线程使用,它 在 Java 中执行 Hashtable。
HashMap 不保证地图的顺序会随着时间的推移保持不变。
请注意,HashMap 可以通过以下方式进行同步
Map m = Collections.synchronizedMap(hashMap);
总而言之,Hashtable 和 Java 中的 HashMap,例如线程安全和速度,仅基于此 如果你绝对需要线程安全,如果你正在运行 Java 5 考虑在 Java 中使用 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);
Hashtable:
Hashtable 是一种保留键值对值的数据结构。它不允许键和值都为 null。如果添加 null 值,则将得到一个。它是同步的。所以它有它的成本。在特定时间,只有一个线程可以访问 HashTable。NullPointerException
示例:
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));
}
}
同步或线程安全:
哈希映射不同步,因此它不安全,如果没有适当的同步块,它不能在多个线程之间共享,而哈希表是同步的,因此它是线程安全的。
Null 键和 null 值:
HashMap 允许一个 null 键和任意数量的 null 值。哈希表不允许 null 键或值。
迭代值:
HashMap 中的迭代器是一个快速失败的迭代器,而 Hashtable 的枚举器不是,如果任何其他线程通过添加或删除除 Iterator 自己的 remove() 方法之外的任何元素在结构上修改映射,则抛出 ConcurrentModificationException。
超类和遗产:
HashMap 是 AbstractMap 类的子类,而 Hashtable 是 Dictionary 类的子类。
性能 :
由于 HashMap 不同步,因此与 Hashtable 相比,它的速度更快。
有关与 Java 集合相关的示例和面试问题和测验,请参阅 http://modernpathshala.com/Article/1020/difference-between-hashmap-and-hashtable-in-java
除了前面提到的差异之外,需要注意的是,从 Java 8 开始,将每个存储桶中使用的 Nodes(链表)动态替换为 TreeNodes(红黑树),因此即使存在高哈希冲突,搜索时最坏的情况是HashMap
O(log(n)) 表示 Vs O(n)。HashMap
Hashtable
*上述改进尚未应用于,而仅适用于 、 和 。Hashtable
HashMap
LinkedHashMap
ConcurrentHashMap
仅供参考,目前,
TREEIFY_THRESHOLD = 8
:如果一个存储桶包含8个以上的节点,则链表将转换为平衡树。UNTREEIFY_THRESHOLD = 6
:当存储桶变得太小时(由于删除或调整大小),树将转换回链表。
评论
已经发布了许多好的答案。我补充了一些新观点并总结了一下。
HashMap
两者都用于以键和值形式存储数据。两者都使用哈希技术来存储唯一密钥。
但是下面给出的 HashMap 和 Hashtable 类之间存在许多差异。Hashtable
哈希图
HashMap
是非同步的。它不是线程安全的,如果没有正确的同步代码,则无法在多个线程之间共享。HashMap
允许一个 null 键和多个 null 值。HashMap
是 JDK 1.2 中引入的新类。HashMap
速度很快。- 我们可以通过调用此代码使 as 同步
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 有什么区别?
评论
Hashtable 类是同步的,也就是说,它被设计为由处理多个或多线程进程的应用程序使用。在应用程序到进程的经典情况下,同步类的效率较低,因此 Hashmap 类通常更快。 HashTable 类不接受键或值的 Null 值,而 HashMap 类允许单个键为 Null 且尽可能多的 null。
集合
(有时称为容器)只是一个将多个元素组合成一个单元的对象。集合
用于存储、检索、操作和传达聚合数据。集合框架 W 是用于表示和操作集合的统一体系结构。
JDK1.2
和 Hashtable JDK1.0
都用于表示成对表示的一组对象。每一对都称为对象。条目的集合由 和 的对象引用。集合中的键必须是唯一的或独特的。[因为它们用于检索特定键的映射值。 集合中的值可以重复。HashMap
<Key, Value>
<Key, Value>
Entry
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 { ... }
« 初始容量和负载系数
容量是 Hashtable 中的存储桶数量,初始容量只是创建 Hashtable 时的容量。请注意,哈希表是打开的:在哈希冲突的情况下,单个存储桶存储多个条目,必须按顺序搜索这些条目。负载因子是衡量哈希表在容量自动增加之前允许的满量。
HashMap 使用默认初始容量 (16) 和默认负载因子 (0.75) 构造一个空的 Hashtable。其中,as Hashtable 构造具有默认初始容量 (11) 和负载因子/填充比 (0.75) 的空 Hashtable。
« 哈希冲突时的结构修改
HashMap,Hashtable
,在发生哈希冲突的情况下,它们将映射条目存储在链表中。 从
Java8 for HashMap
开始,如果哈希桶增长超过某个阈值,则该桶将从条目链表切换到平衡树
。将最坏情况下的性能从 O(n) 提高到 O(log n)。在将列表转换为二叉树时,哈希码用作分支变量。如果同一存储桶中有两个不同的哈希码,则一个哈希码被认为更大,位于树的右侧,另一个位于树的左侧。但是,当两个哈希码相等时,HashMap
会假设键是可比的,并比较键以确定方向,以便可以保持某种顺序。使 HashMap
的键具有可比性是一种很好的做法。在添加条目时,如果存储桶大小达到 TREEIFY_THRESHOLD = 8
,则将条目链表转换为平衡树,在删除小于 TREEIFY_THRESHOLD
且最多 UNTREEIFY_THRESHOLD = 6
的条目时,会将平衡树重新转换为条目链表。Java 8 SRC,堆栈发布
« 集合视图迭代、快速故障和故障安全
+--------------------+-----------+-------------+
| | Iterator | Enumeration |
+--------------------+-----------+-------------+
| Hashtable | fail-fast | safe |
+--------------------+-----------+-------------+
| HashMap | fail-fast | fail-fast |
+--------------------+-----------+-------------+
| ConcurrentHashMap | safe | safe |
+--------------------+-----------+-------------+
迭代器
本质上是一种快速故障。也就是说,如果集合在迭代时被修改,而不是它自己的 remove() 方法,它会抛出 ConcurrentModificationException。其中,枚举
本质上是故障安全的。如果在迭代时修改了集合,则不会引发任何异常。
根据 Java API 文档,迭代器始终优先于枚举。
注意:Enumeration 接口的功能由 Iterator 接口复制。此外,Iterator 还添加了可选的删除操作,并且具有较短的方法名称。新实现应考虑优先使用 Iterator 而不是 Enumeration。
在 Java 5 中引入了 ConcurrentMap 接口: - 一个由哈希表支持的高度并发、高性能的实现。此实现在执行检索时永远不会阻塞,并允许客户端选择更新的并发级别。它旨在作为 的直接替代品 : 除了实现 之外,它还支持所有 特有的“遗留”方法。ConcurrentHashMap
ConcurrentMap
Hashtable
ConcurrentMap
Hashtable
每个 s 值都是易失性的,从而确保了竞争修改和后续读取的细粒度一致性;每次读取都反映最近完成的更新
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();
}
}
« Null 键和 Null 值
HashMap
最多允许一个 null 键和任意数量的 null 值。其中 as 甚至不允许单个 null 键和 null 值,如果键或值为 null,则会引发 NullPointerException。例Hashtable
« 同步,线程安全
Hashtable
在内部同步。因此,在多线程应用程序中使用是非常安全的。其中 as 不是内部同步的。因此,在没有外部同步的情况下在多线程应用程序中使用是不安全的。您可以使用方法进行外部同步。Hashtable
HashMap
HashMap
HashMap
Collections.synchronizedMap()
« 性能
由于是内部同步的,这使得速度比 .Hashtable
Hashtable
HashMap
@See
HashMap 和 Hashtable 都用于以键和值形式存储数据。两者都使用哈希技术来存储唯一密钥。 下面给出的 HashMap 和 Hashtable 类之间存在许多差异。
下一个:从数组创建 ArrayList
评论
ConcurrentMap
,因为问题说的是“非线程应用程序”,这意味着线程/并发不是问题。传统上选择 HashTable
只是因为它的部分线程保护。但ConcurrentHashMap
已经避免了这一点,因此它通常被视为已停用。通常建议在HashMap 或
ConcurrentHashMap
之间进行选择。我相信这是一个明智的评论,如果这是她的意思的话。