【JAVA】七 JAVA Dictionary 一 Hashtable
JDK API
java.util
Class Dictionary
Direct Known Subclasses:
Hashtable
Dictionary
abstract class Dictionary 定义 ,如果看过我关于Map的介绍,那么你一定不陌生,此处的方法在java.util.Map中已经见到过.
public abstract
class Dictionary<K,V> {
public Dictionary() {}
abstract public int size();
abstract public boolean isEmpty();
abstract public Enumeration<K> keys();
abstract public Enumeration<V> elements();
abstract public V get(Object key);
abstract public V put(K key, V value);
abstract public V remove(Object key);
}
Hashtable 属性
public class Hashtable<K,V>
extends Dictionary<K,V>
implements Map<K,V>, Cloneable, java.io.Serializable {
/**
* 大家注意 这里的 Entry class implements java.util.Map.Entry
*/
private transient Entry[] table;
/**
* 哈希表中的条目的总数.
* 还记的 HashMap吗 , 那里记录总数是用的 size 属性 .
*/
private transient int count;
/**
* 要调整大小的极限值(容量*默认计算阀值参数因子)
* (capacity * loadFactor).)
*/
private int threshold;
/**
* 阀值参数因子
*/
private float loadFactor;
/**
* 这个Hashtable结构修改的次数
* 结构修改是那些改变的映射
* Hashtable或修改其内部结构(例如重复)。
* 这个字段是用来使迭代器的集合视图 Hashtable很快失败。
* (见ConcurrentModificationException)。
*/
private transient int modCount = 0;
}
Hashtable 构造方法
/**
* 指定Hashtable 的初始大小 , 阀值参数因子
*/
public Hashtable(int initialCapacity, float loadFactor) {
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
if (loadFactor <= 0 || Float.isNaN(loadFactor))
throw new IllegalArgumentException("Illegal Load: "+loadFactor);
if (initialCapacity==0)
initialCapacity = 1;
this.loadFactor = loadFactor;
table = new Entry[initialCapacity];
threshold = (int)(initialCapacity * loadFactor);
}
/**
* 指定Hashtable 的初始大小
*/
public Hashtable(int initialCapacity) {
this(initialCapacity, 0.75f);
}
/**
* 默认初始大小11
* 阀值参数因子 (0.75).
*/
public Hashtable() {
this(11, 0.75f);
}
/**
* 接收 java.util.Map 子集 ,
* 如果参数长度大于 11 ,那么新 Hashtable 长度是参数长度的 2 倍 .
* 阀值参数因子 (0.75).
*/
public Hashtable(Map<? extends K, ? extends V> t) {
this(Math.max(2*t.size(), 11), 0.75f);
putAll(t);
}
Hashtable 扩大容量
在put方法中判断 count 大于等于 threshold 就会给Hashtable扩大容量,
原始大小 * 2 + 1
扩大容量和HashMap一样是非常消耗性能的操作,
因为要重新计算hash值,元素越多越销毁性能.
允许 null key 不允许 null value
public synchronized V put(K key, V value) {
// Make sure the value is not null
if (value == null) {
throw new NullPointerException();
}
// Makes sure the key is not already in the Hashtable.
Entry tab[] = table;
int hash = hash(key);
int index = (hash & 0x7FFFFFFF) % tab.length;
for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {
if ((e.hash == hash) && e.key.equals(key)) {
V old = e.value;
e.value = value;
return old;
}
}
modCount++;
if (count >= threshold) {
// Rehash the table if the threshold is exceeded
rehash();
tab = table;
hash = hash(key);
index = (hash & 0x7FFFFFFF) % tab.length;
}
// Creates the new entry.
Entry<K,V> e = tab[index];
tab[index] = new Entry<>(hash, key, value, e);
count++;
return null;
}
protected void rehash() {
int oldCapacity = table.length;
Entry<K,V>[] oldMap = table;
// overflow-conscious code
int newCapacity = (oldCapacity << 1) + 1;
if (newCapacity - MAX_ARRAY_SIZE > 0) {
if (oldCapacity == MAX_ARRAY_SIZE)
// Keep running with MAX_ARRAY_SIZE buckets
return;
newCapacity = MAX_ARRAY_SIZE;
}
Entry<K,V>[] newMap = new Entry[newCapacity];
modCount++;
threshold = (int)Math.min(newCapacity * loadFactor, MAX_ARRAY_SIZE + 1);
boolean rehash = initHashSeedAsNeeded(newCapacity);
table = newMap;
for (int i = oldCapacity ; i-- > 0 ;) {
for (Entry<K,V> old = oldMap[i] ; old != null ; ) {
Entry<K,V> e = old;
old = old.next;
if (rehash) {
e.hash = hash(e.key);
}
int index = (e.hash & 0x7FFFFFFF) % newCapacity;
e.next = newMap[index];
newMap[index] = e;
}
}
}
Hashtable 线程安全
来简单的看几个方法
public synchronized V put(K key, V value) ...
public synchronized V get(Object key) ...
public synchronized V remove(Object key) ...
public synchronized int size() ...
...
Hashtable.Entry implements Map.Entry
内部静态类Entry与HashMap.Entry一样都是实现了Map.Entry接口
private static class Entry<K,V> implements Map.Entry<K,V> {
...
Hashtable添加值 hashCode 相同 / fail-fast机制
请参考我的另一篇文章HashMap添加值 hashCode 相同,实现原理相同 .
http://blog.csdn.net/maguochao_mark/article/details/51496513