原文: https://howtodoinjava.com/java/collections/hashtable-class/
Java Hashtable类是哈希表数据结构的实现。 它与 Java 中的HashMap非常相似,最显着的区别是Hashtable是同步的而HashMap不是。
在此哈希表教程中,我们将学习它的内部结构,构造器,方法,用例和其他要点。
Table of Contents1\. How Hashtable Works?2\. Hashtable Features3\. Hashtable Constructors4\. Hashtable Methods5\. Hashtable Example6\. Hashtable Performance6\. Hashtable vs HashMap8\. Conclusion
1. Hashtable如何工作?
Hashtable内部包含存储键/值对的存储桶。 哈希表使用键的哈希码确定键/值对应映射到哪个存储桶。

Java 哈希表
从键的哈希码中获取存储桶位置的函数称为哈希函数。 从理论上讲,哈希函数是一种函数,当给定键时,该函数会在表中生成地址。 哈希函数总是返回对象的数字。 两个相等的对象将始终具有相同的数字,而两个不相等的对象可能并不总是具有不同的数字。
当我们将对象放入哈希表时,不同的对象(通过equals()方法)可能具有相同的哈希码。 这称为冲突。 为了解决冲突,哈希表使用列表的数组。 映射到单个存储桶(数组索引)的对存储在列表中,列表引用存储在数组索引中。

哈希冲突
1.1 Hashtable声明
Hashtable类在 Java 中声明如下。 它扩展了字典类,并且实现Map ,Cloneable和Serializable接口。 'K'是键的类型,'V'是键的映射值的类型。
public class Hashtable<K,V>
extends Dictionary<K,V>
implements Map<K,V>, Cloneable, java.io.Serializable
{
//implementation
}
2. Hashtable特性
有关 Java Hashtable类的重要知识是:
- 它类似于
HashMap,但是它是同步的,而HashMap没有同步。 - 它不接受
null键或值。 - 它不接受重复的键。
- 它将键值对存储在内部维护列表数组的哈希表数据结构中。 每个列表可以被称为桶。 如果发生冲突,则将对存储在此列表中。
Hashtable中的枚举器不是快速失败的。
3. Hashtable构造器
Hashtable类具有四个构造器。
Hashtable():这是默认构造器。 它使用默认的初始容量(11)和负载因子(0.75)构造一个新的空哈希表。Hashtable(int size):它构造一个具有指定初始大小的新的空哈希表。Hashtable(int size, float fillRatio):构造一个具有指定初始大小和填充率的新的空哈希表。Hashtable(Map m):构造一个哈希表,该哈希表使用指定映射中的键值对初始化。
请注意,初始容量是指哈希表中的存储桶数。 需要最佳数量的存储桶来存储具有最小冲突(以提高性能)和有效内存利用率的键值对。
填充率确定在增加哈希表的容量之前可以达到多少。 它的值介于 0.0 到 1.0 之间。
4. Hashtable方法
Hashtable类中的方法与HashMap非常相似。 看一看。
void clear():用于删除哈希表中的所有对。boolean contains(Object value):如果哈希表中存在任何对,则返回true,否则返回false。 注意,该方法的特性与containsValue()特性相同。boolean containsValue(Object value):如果哈希表中存在任何对,则返回true,否则返回false。boolean containsKey(Object key):如果哈希表中存在任何对,则返回true,否则返回false。boolean isEmpty():如果哈希表为空,则返回true;否则,返回 0。 如果它包含至少一个键,则返回false。void rehash():用于增加哈希表的大小并重新哈希其所有键。Object get(对象键):它返回指定键所映射到的值。 如果找不到这样的键,则返回null。Object put(Object key, Object value):它将哈希表中指定的key映射到指定的value。 键和值都不能为null。Object remove(Object key):它从哈希表中删除键(及其对应的值)。int size():它返回哈希表中的条目数。
5. Hashtable示例
我们来看一个有关如何在 Java 程序中使用哈希表的示例。
import java.util.Hashtable;
import java.util.Iterator;
public class HashtableExample
{
public static void main(String[] args)
{
//1\. Create Hashtable
Hashtable<Integer, String> hashtable = new Hashtable<>();
//2\. Add mappings to hashtable
hashtable.put(1, "A");
hashtable.put(2, "B" );
hashtable.put(3, "C");
System.out.println(hashtable);
//3\. Get a mapping by key
String value = hashtable.get(1); //A
System.out.println(value);
//4\. Remove a mapping
hashtable.remove(3); //3 is deleted
//5\. Iterate over mappings
Iterator<Integer> itr = hashtable.keySet().iterator();
while(itr.hasNext())
{
Integer key = itr.next();
String mappedValue = hashtable.get(key);
System.out.println("Key: " + key + ", Value: " + mappedValue);
}
}
}
程序输出。
{3=C, 2=B, 1=A}
A
Key: 2, Value: B
Key: 1, Value: A
6. Hashtable性能
对于大多数常见操作(例如get(),put(),contains()等),与Hashtable中的O(n)相比,性能明智的HashMap在 O(log(n))中执行。
Hashtable中朴素的线程安全方法(“同步每个方法”)使线程应用程序变得更加糟糕。 我们最好从外部同步HashMap。 一个经过深思熟虑的设计将比Hashtable表现更好。
哈希表已过时。 最好是使用ConcurrentHashMap类,它们提供更高的并发度。
7. Hashtable与HashMap
让我们快速列出 Java 中hashmap和hashtable之间的差异。
HashMap不同步。 哈希表已同步。HashMap允许一个空键和多个空值。 哈希表不允许使用任何null键或值。HashMap很快。 由于增加了同步,哈希表很慢。HashMap被Iterator遍历。Hashtable被Enumerator和Iterator遍历。HashMap中的迭代器是快速失败的。Hashtable中的枚举器不是快速失败的。HashMap继承AbstractMap类。Hashtable继承Dictionary类。
8. 总结
在本教程中,我们了解了 Java Hashtable类,其构造器,方法,现实用例,并比较了它们的性能。 我们还了解了hastable与 Java 中的hashmap有何不同。
不要在新应用程序中使用哈希表。 如果不需要并发,请使用HashMap。 在并发环境中,更喜欢使用ConcurrentHashMap。
在评论中把您的问题交给我。
学习愉快!
参考:
