java 集合系列目录:
Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例
Java 集合系列 04 LinkedList详细介绍(源码解析)和使用示例
Java 集合系列 05 Vector详细介绍(源码解析)和使用示例
Java 集合系列 06 Stack详细介绍(源码解析)和使用示例
Java 集合系列 07 List总结(LinkedList, ArrayList等使用场景和性能分析)
Java 集合系列 09 HashMap详细介绍(源码解析)和使用示例
Java 集合系列 10 Hashtable详细介绍(源码解析)和使用示例
前一章,我们学习了HashMap。这一章,我们对Hashtable进行学习。
我们先对Hashtable有个整体认识,然后再学习它的源码,
第1部分 Hashtable介绍
第2部分 Hashtable数据结构
第3部分 Hashtable源码解析(基于JDK1.7.0_45)
第4部分 Hashtable遍历方式
第1部分 Hashtable介绍
Hashtable 简介
和HashMap一样,Hashtable 也是一个散列表,它存储的内容是键值对(key-value)映射。
Hashtable 继承于Dictionary,实现了Map、Cloneable、java.io.Serializable接口。
Hashtable 的函数都是同步的,这意味着它是线程安全的。它的key、value都不可以为null。此外,Hashtable中的映射不是有序的。
此类实现一个哈希表,该哈希表将键映射到相应的值。任何非 null
对象都可以用作键或值。
为了成功地在哈希表中存储和获取对象,用作键的对象必须实现 hashCode
方法和 equals
方法。
Hashtable 的实例有两个参数影响其性能:初始容量 和 加载因子。容量 是哈希表中桶 的数量,初始容量 就是哈希表创建时的容量。注意,哈希表的状态为 open:在发生“哈希冲突”的情况下,单个桶会存储多个条目,这些条目必须按顺序搜索。加载因子 是对哈希表在其容量自动增加之前可以达到多满的一个尺度。初始容量和加载因子这两个参数只是对该实现的提示。关于何时以及是否调用 rehash 方法的具体细节则依赖于该实现。
通常,默认加载因子是 0.75, 这是在时间和空间成本上寻求一种折衷。加载因子过高虽然减少了空间开销,但同时也增加了查找某个条目的时间(在大多数 Hashtable 操作中,包括 get 和 put 操作,都反映了这一点)。
Hashtable的构造函数
// 默认构造函数。 public Hashtable() // 指定“容量大小”的构造函数 public Hashtable(int initialCapacity) // 指定“容量大小”和“加载因子”的构造函数 public Hashtable(int initialCapacity, float loadFactor) // 包含“子Map”的构造函数 public Hashtable(Map<? extends K, ? extends V> t)
Hashtable的API
void clear() 将此哈希表清空,使其不包含任何键。 Object clone() 创建此哈希表的浅表副本。 boolean contains(Object value) 测试此映射表中是否存在与指定值关联的键。 boolean containsKey(Object key) 测试指定对象是否为此哈希表中的键。 boolean containsValue(Object value) 如果此 Hashtable 将一个或多个键映射到此值,则返回 true。 Enumeration<V> elements() 返回此哈希表中的值的枚举。 Set<Map.Entry<K,V>> entrySet() 返回此映射中包含的键的 Set 视图。 boolean equals(Object o) 按照 Map 接口的定义,比较指定 Object 与此 Map 是否相等。 V get(Object key) 返回指定键所映射到的值,如果此映射不包含此键的映射,则返回 null. 更确切地讲,如果此映射包含满足 (key.equals(k)) 的从键 k 到值 v 的映射,则此方法返回 v;否则,返回 null。 int hashCode() 按照 Map 接口的定义,返回此 Map 的哈希码值。 boolean isEmpty() 测试此哈希表是否没有键映射到值。 Enumeration<K> keys() 返回此哈希表中的键的枚举。 Set<K> keySet() 返回此映射中包含的键的 Set 视图。 V put(K key, V value) 将指定 key 映射到此哈希表中的指定 value。 void putAll(Map<? extends K,? extends V> t) 将指定映射的所有映射关系复制到此哈希表中,这些映射关系将替换此哈希表拥有的、针对当前指定映射中所有键的所有映射关系。 protected void rehash() 增加此哈希表的容量并在内部对其进行重组,以便更有效地容纳和访问其元素。 V remove(Object key) 从哈希表中移除该键及其相应的值。 int size() 返回此哈希表中的键的数量。 String toString() 返回此 Hashtable 对象的字符串表示形式,其形式为 ASCII 字符 ", " (逗号加空格)分隔开的、括在括号中的一组条目。 Collection<V> values() 返回此映射中包含的键的 Collection 视图。
第2部分 Hashtable数据结构
Hashtable的继承关系
java.lang.Object ? java.util.Dictionary<K, V> ? java.util.Hashtable<K, V> public class Hashtable<K,V> extends Dictionary<K,V> implements Map<K,V>, Cloneable, java.io.Serializable { }
Hashtable与Map关系如下图:
从图中可以看出:
(01) Hashtable继承于Dictionary类,实现了Map接口。Map是"key-value键值对"接口,Dictionary是声明了操作"键值对"函数接口的抽象类。
(02) Hashtable是通过"拉链法"实现的哈希表。它包括几个重要的成员变量:table, count, threshold, loadFactor, modCount。
table是一个Entry[]数组类型,而Entry实际上就是一个单向链表。哈希表的"key-value键值对"都是存储在Entry数组中的。
count是Hashtable的大小,它是Hashtable保存的键值对的数量。
threshold是Hashtable的阈值,用于判断是否需要调整Hashtable的容量。threshold的值="容量*加载因子"。
loadFactor就是加载因子。
modCount是用来实现fail-fast机制的
第3部分 Hashtable源码解析(基于JDK1.7.0_45)
为了更了解Hashtable的原理,下面对Hashtable源码代码作出分析。