Java集合框架中的Hashtable,HashMap,HashSet,哈希表概念

问题描述 投票:6回答:4

我正在学习Java Collection Framework并获得了适度的理解。现在,当我走得更远时,我有一些疑惑:HashMapHashSetHashtable

HashMap的Javadoc说:

基于哈希表的Map接口实现。此实现提供所有可选的映射操作,并允许空值和空键。

HashSet的Javadoc说:

此类实现Set接口,由哈希表(实际上是HashMap实例)支持。它不能保证集合的迭代顺序;特别是,它不保证订单会随着时间的推移保持不变。

Hashtable的Javadoc说:

该类实现了一个哈希表,它将键映射到值。任何非null对象都可以用作键或值。

让所有人都实施hash table令人困惑。他们实现哈希表的概念吗?

似乎所有这些都是相互关联的,但我无法完全理解它。

任何人都可以用简单的语言帮助我理解这个概念。

java hash hashmap hashtable hashset
4个回答
14
投票

Java的SetMap接口指定了两种截然不同的集合类型。从概念上讲,Map恰如其分:从一组对象(键)到另一组(值)的映射。 Set也就是它的声音:一组物体(没有其他结构)。 HashtableHashMap都实现了MapHashSet实现了Set,并且它们都使用哈希码来包含集合中的键/对象以提高性能。

HashtableHashMap

Hashtable是一个遗产类,几乎总是应该避免使用HashMap。它们基本上是相同的,除了Hashtable中的大多数方法都是同步的,使得单个方法调用是线程安全的.1如果使用多个线程和HashMap,则必须提供自己的同步或其他线程安全机制。

Hashtable的问题在于同步每个方法调用(这是一个不重要的操作)通常是错误的。您根本不需要同步,或者从应用程序逻辑的角度来看,您需要在跨多个方法调用的事务上进行同步。由于在不破坏现有代码的情况下简单地从Hashtable中删除方法级同步是不可能的,因此Collections框架作者需要提出一个新类;因此HashMap。这也是一个更好的名字,因为很明显它是一种Map

哦,如果你确实需要方法级同步,你仍然不应该使用Hashtable。相反,您可以调用Collections.synchronizedMap()将任何地图转换为同步地图。或者,您可以使用ConcurrentHashMap,根据the docs:“遵循与Hashtable相同的功能规范”但具有更好的性能和附加功能(例如putIfAbsent())。

1还有其他差异(在我看来不太重要),例如HashMap支持null值和键。

HashSet

在功能方面,HashSetHashMap无关。碰巧在内部使用HashMap来实现Set功能。出于某种原因,Collections框架开发人员认为将此内部实现细节作为该类的公共规范的一部分是个好主意。 (在我看来,这是一个错误。)


3
投票

Hashtable是一个在Java具有泛型之前创建的旧类。它仍然只是为了向后兼容。请改用HashMap。

如果不需要将键映射到值,请使用HashSet。它建立在与哈希表相同的算法上,但它用于一个根本不同的目的。


1
投票

HashMap和HashTable都继承了Map接口,并且具有几乎相同的工作和属性。但主要区别如下: -

1.Hashmap是键和值对的无序映射。我们可以在hashmap中使用null键或值对。同样,hashmap是不同步的(即不是线程安全的多线程可以同时访问和修改它。)但是我们可以在外部创建一个hashmap thread-safe.So如果我们不考虑同步问题,那么hashmap是更可取的。

2.HashTable: - 一个同步的hashMap(即线程安全的hashmap)。但是在这种情况下,键和值对永远不会为null。在Hashtable中,我们指定一个用作键的对象,以及我们想要的值与该密钥相关联。然后对密钥进行散列,并将得到的散列代码用作值存储在表中的索引

3.HashSet:-A hashset继承set接口,最后它也基于hashtable(或者我们可以说只与我们的hashmap深度连接)但在这种情况下,key和values对总是唯一的,不允许重复值。但是null允许键值。根据哈希码插入对象。

总之,我们可以说三个集合都已连接到Map接口和all。


-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,这是因为这个对象是不可变的,它们可以是这个实现的好键,或者你可以创建自己的不可变类并将它用作键。使用不可变对象作为键是很好的做法,因为在创建之后它们无法改变它们的状态,因此哈希码总是相同的。

© www.soinside.com 2019 - 2024. All rights reserved.