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

Cur*_*ind 11 java hash hashtable hashmap hashset

我正在学习Java Collection Framework并获得了适度的理解.现在,当我走得更远一点我得到了一些疑惑:HashMap,HashSet,Hashtable.

Javadoc HashMap说:

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

Javadoc HashSet说:

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

Javadoc Hashtable说:

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

令人困惑的是,所有这些都实现了hash table.难道他们实现概念哈希表

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

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

Ted*_*opp 26

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

HashtableHashMap

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

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

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

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

HashSet

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

  • 这是解决我的困惑的最有见地的答案之一。谢谢你特德·霍普!我当时想,为什么 Hashtable 不是驼峰式大小写和同步的……,而是 HashMap/HashSet 驼峰式大小写和同步的;你的回答解释了这一点。 (4认同)

Bee*_*ter 5

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

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

  • 自从引入泛型以来,`Hashtable` 也一直是一个泛型类。 (2认同)