我正在学习 Java Collection Framework 并获得了适度的理解。现在,当我走得更远时,我有一些疑问: HashMap
, HashSet
, Hashtable
HashMap
的 Javadoc 说:
Map 接口的基于哈希表的实现。此实现提供所有可选的映射操作,并允许空值和空键。
HashSet
的 Javadoc 说:
此类实现 Set 接口,由哈希表(实际上是一个 HashMap 实例)支持。它不保证集合的迭代顺序;特别是,它不保证顺序会随着时间的推移保持不变。
Hashtable
的 Javadoc 说:
此类实现了一个哈希表,它将键映射到值。任何非空对象都可以用作键或值。
令人困惑的是,它们都实现了 hash table
。他们是否实现了 哈希表 的 概念?
这些似乎都是相互关联的,但我无法完全理解。
谁能用简单的语言帮助我理解这个概念。
原文由 CuriousMind 发布,翻译遵循 CC BY-SA 4.0 许可协议
Java 的
Set
和Map
接口指定了两种截然不同的集合类型。 ASet
顾名思义:不同(不相等)对象的集合,没有其他结构。 AMap
从概念上讲,也正是它听起来的样子:从一组对象(不同的键)到一组对象(值)的映射。Hashtable
andHashMap
both implementMap
,HashSet
implementsSet
, and they all use hash codes for keys/集合中包含的对象以提高性能。Hashtable
和HashMap
Hashtable
是一个遗留类,几乎总是应该避免支持HashMap
。它们本质上做同样的事情,除了Hashtable
中的大多数方法是同步的,使单个方法调用线程安全。 1如果您使用多线程和HashMap
,则必须提供自己的同步或其他线程安全机制。Hashtable
的问题是同步每个方法调用(这是一个重要的操作)通常是错误的。您要么根本不需要同步,要么从应用程序逻辑的角度来看,您需要对跨越多个方法调用的事务进行同步。由于不可能在不破坏现有代码的情况下简单地从Hashtable
中删除方法级同步,因此集合框架作者需要提出一个新类;因此HashMap
。它也是一个更好的名字,因为很明显它是一种Map
。哦,如果你确实需要方法级同步,你仍然不应该使用
Hashtable
。相反,您可以调用Collections.synchronizedMap()
将任何地图转换为同步地图。或者,您可以使用ConcurrentHashMap
,根据 文档:“遵循与Hashtable
相同的功能规范”但具有更好的性能和附加功能(例如putIfAbsent()
)。1还有其他差异(在我看来不太重要),例如
HashMap
支持null
值和键。HashSet
在功能方面,
HashSet
与HashMap
无关。它恰好在内部使用HashMap
来实现Set
功能。出于某种原因,集合框架开发人员认为将此内部实现细节作为类公共规范的一部分是个好主意。 (在我看来,这是一个错误。)