我正在学习Java Collection Framework并获得了适度的理解。现在,当我走得更远时,我怀疑:another_one =
"what I originally had
across multiple lines"
,HashMap
,HashSet
。
Hashtable
的Javadoc说:
基于哈希表的Map接口实现。这个 实现提供了所有可选的map操作,以及 允许空值和空键。
HashMap
的Javadoc说:
此类实现Set接口,由哈希表支持 (实际上是一个HashMap实例)。它不能保证 集合的迭代顺序;特别是,它并不保证 订单会随着时间的推移保持不变。
HashSet
的Javadoc说:
此类实现一个哈希表,它将键映射到值。任何 非null对象可以用作键或值。
令人困惑的是,所有这些都实现了Hashtable
。他们是否实施了哈希表的概念?
似乎所有这些都是相互关联的,但我无法完全理解它。
任何人都可以用简单的语言帮助我理解这个概念。
答案 0 :(得分:14)
Java的Set
和Map
接口指定了两种截然不同的集合类型。概念上,Map
就是它的含义:从一组对象(键)到另一组(值)的映射。 Set
也就是它的声音:一组对象(没有其他结构)。 Hashtable
和HashMap
都实现Map
,HashSet
实现Set
,并且它们都对集合中包含的键/对象使用哈希码来提高性能。< / p>
Hashtable
和HashMap
Hashtable
是一个遗留类,几乎总是应该避免使用HashMap
。它们基本上是相同的,除了Hashtable
中的大多数方法都是同步的,使得单个方法调用是线程安全的。 1 如果你是必须提供自己的同步或其他线程安全机制使用多个线程和HashMap
。
Hashtable
的问题是同步每个方法调用(这是一个无关紧要的操作)通常是错误的。您根本不需要同步,或者从应用程序逻辑的角度来看,您需要在跨多个方法调用的事务上进行同步。由于在不破坏现有代码的情况下简单地从Hashtable
删除方法级同步是不可能的,因此Collections框架作者需要提出一个新类;因此HashMap
。它也是一个更好的名称,因为很明显它是一种Map
。
哦,如果你确实需要方法级同步,你仍然不应该使用Hashtable
。相反,您可以调用Collections.synchronizedMap()
将任何地图转换为同步地图。或者,您可以使用ConcurrentHashMap
,根据the docs:&#34;遵守与Hashtable
&#34;相同的功能规范。但具有更好的性能和附加功能(例如putIfAbsent()
)。
1 还有其他差异(在我看来不太重要),例如HashMap
支持null
值和键。
<强> HashSet
强>
就功能而言,HashSet
与HashMap
无关。它恰好在内部使用HashMap
来实现Set
功能。出于某种原因,Collections框架开发人员认为将此内部实现细节作为该类的公共规范的一部分是个好主意。 (在我看来,这是一个错误。)
答案 1 :(得分:3)
Hashtable是一个在Java具有泛型之前创建的旧类。它仍然只是为了向后兼容。改为使用HashMap。
当您不需要将键映射到值时使用HashSet。它建立在与哈希表相同的算法上,但它用于一个根本不同的目的。
答案 2 :(得分:1)
HashMap和HashTable都继承了Map接口。并且具有几乎相同的工作和属性。但主要区别如下: -
1.Hashmap是键和值对的无序映射。我们可以在hashmap内部使用null键或值对。同样,hashmap是不同步的(即不是线程安全的多线程可以在同一时间访问和修改它)但是我们可以在外部制作一个hashmap thread-safe.So如果我们不考虑同步问题,那么最好使用hashmap。
总之,我们可以说这三个集合都已连接到Map接口和所有。
答案 3 :(得分:-1)
Hashtable是同步的,但HashMap不是,但你可以通过方法Collections.synchronizedMap()的帮助使HashMap同步。 Hashtable,HashMap和HashSet基于Hash Table数据结构进行了调用。您可以使用一个空键以及您希望HashMap使用哪种空值,但Hashtable不允许使用null键或空值。基本上在HashSet下工作HashMap,其中value是Object,因此HashSet值是唯一的,因为HashMap键是唯一的。因此,为了将键值对放在Hashmap或Hashtable中或将元素放入HashSet,您需要使用Object类中的hashcode和equals方法来修正此实现的工作。这是因为在此实现中使用哈希表算法和哈希码,需要等于将值放入右桶。重要的是要知道你需要使用键字符串或任何其他包装类,比如我们的Integer,这是因为这个对象是不可变的,它们可以是这个实现的好键,或者你可以创建自己的不可变类并将它用作键。使用不可变对象作为关键是好习惯,因为在创建之后它们无法改变它们的状态,因此哈希码总是相同的。