java -- HashTable
特点
- HashTable 是一个散列表,它存储的内容是键值对(key-value)映射。
- HashTable 继承于Dictionary,实现了Map、Cloneable、java.io.Serializable接口。
- HashTable 的实现同步的,这意味着它是线程安全的。它的key、value都不可以为null。此外,HashTable中的映射不是有序的。
跟HashMap的区别
- HashTable是线程安全,HashMap不是
- HashTable不允许key和value为null,HashMap允许
扩容
- 初始容量:哈希表在创建时的容量,默认是16
- 加载因子:哈希表在其容量自动增加之前可以达到多满的一种尺,默认是0.75
当哈希表的容量超过 初始容量 * 加载因子,就会触发扩容,扩容后的哈希表大概是原来的两倍。
如何选择初始容量和加载因子
通常,默认加载因子是 0.75, 这是在时间和空间成本上寻求一种折中。加载因子过高虽然减少了空间开销,但同时也增加了查询成本(在大多数 HashMap 类的操作中,包括 get 和 put 操作,都反映了这一点)。在设置初始容量时应该考虑到映射中所需的条目数及其加载因子,以便最大限度地减少 rehash 操作次数。如果初始容量大于最大条目数除以加载因子,则不会发生 rehash 操作。
HashTable的构造函数
// 默认构造函数。
public Hashtable()
// 指定“容量大小”的构造函数
public Hashtable(int initialCapacity)
// 指定“容量大小”和“加载因子”的构造函数
public Hashtable(int initialCapacity, float loadFactor)
// 包含“子Map”的构造函数
public Hashtable(Map<? extends K, ? extends V> t)
HashTable的API
synchronized void clear()
synchronized Object clone()
boolean contains(Object value)
synchronized boolean containsKey(Object key)
synchronized boolean containsValue(Object value)
synchronized Enumeration<V> elements()
synchronized Set<Entry<K, V>> entrySet()
synchronized boolean equals(Object object)
synchronized V get(Object key)
synchronized int hashCode()
synchronized boolean isEmpty()
synchronized Set<K> keySet()
synchronized Enumeration<K> keys()
synchronized V put(K key, V value)
synchronized void putAll(Map<? extends K, ? extends V> map)
synchronized V remove(Object key)
synchronized int size()
synchronized String toString()
synchronized Collection<V> values()
数据结构
跟前面的HashMap类似,可以参考前面HashMap。同样也存在类似的Hash冲突和性能问题。
性能问题
性能上的原理跟HashMap类似,另外是线程安全的,所以要比HashMap更慢一些。
HashTable遍历方法
方法一
// 假设table是Hashtable对象
// table中的key是String类型,value是Integer类型
Integer integ = null;
Iterator iter = table.entrySet().iterator();
while(iter.hasNext()) {
Map.Entry entry = (Map.Entry)iter.next();
// 获取key
key = (String)entry.getKey();
// 获取value
integ = (Integer)entry.getValue();
}
方法二
// 假设table是Hashtable对象
// table中的key是String类型,value是Integer类型
String key = null;
Integer integ = null;
Iterator iter = table.keySet().iterator();
while (iter.hasNext()) {
// 获取key
key = (String)iter.next();
// 根据key,获取value
integ = (Integer)table.get(key);
}
方法三
// 假设table是Hashtable对象
// table中的key是String类型,value是Integer类型
Integer value = null;
Collection c = table.values();
Iterator iter= c.iterator();
while (iter.hasNext()) {
value = (Integer)iter.next();
}
方法四
- 根据keys()获取Hashtable的集合。
- 通过Enumeration遍历“第一步”得到的集合。
Enumeration enu = table.keys();
while(enu.hasMoreElements()) {
System.out.println(enu.nextElement());
}
方法五
- 根据elements()获取Hashtable的集合。
- 通过Enumeration遍历“第一步”得到的集合。
Enumeration enu = table.elements();
while(enu.hasMoreElements()) {
System.out.println(enu.nextElement());
}