HashTable结构
HashTable与HashMap相似,但是Hashtable继承的是Dictionary,实现的是Map、Cloneable、Serializable接口,与HashMap继承的AbstractMap不同。
内部类
内部类中主要分为两部分,一部分是Map接口规范规定的三种视图,一部分是HashTable实现所需要使用的。
- KeySet
- EntrySet
- ValueCollection
- Entry
- Enumerator
成员
其中也包含了两部分,一部分是实现HashTable所必要的成员,一部分是为Map接口规范中的三个视图所服务的成员。
- table
- count
- threshold
- loadFactor
- modCount
- serialVersion
- MAX_ARRAY_SIZE
- keySet
- entrySet
- values
- KEYS
- VALUES
- ENTRIES
函数
对于HashTable来说封装后暴露给调用者的增删查改等操作都是比较边缘的。核心操作是围绕着Hash算法及表容量。
核心
- rehash()
增加哈希表的容量并在内部重新组织哈希表
protected void rehash() {
int oldCapacity = table.length;
Entry<?,?>[] 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<?,?>[] newMap = new Entry<?,?>[newCapacity];
modCount++;
threshold = (int)Math.min(newCapacity * loadFactor, MAX_ARRAY_SIZE + 1);
table = newMap;
for (int i = oldCapacity ; i-- > 0 ;) {
for (Entry<K,V> old = (Entry<K,V>)oldMap[i] ; old != null ; ) {
Entry<K,V> e = old;
old = old.next;
int index = (e.hash & 0x7FFFFFFF) % newCapacity;
e.next = (Entry<K,V>)newMap[index];
newMap[index] = e;
}
}
}
从代码结构上可以梳理出整个rehash的工作流程:
首先算出扩容后的新容量,再根据容量创建新的Map,将所有与Map有关的参数进行调整,遍历旧的Map并将每个条目重新映射到新Map的对应桶中。
- addEntry()
在Hashtable中添加条目
private void addEntry(int hash, K key, V value, int index) {
modCount++;
Entry<?,?> tab[] = table;
if (count >= threshold) {
// Rehash the table if the threshold is exceeded
rehash();
tab = table;
hash = key.hashCode();
index = (hash & 0x7FFFFFFF) % tab.length;
}
// Creates the new entry.
@SuppressWarnings("unchecked")
Entry<K,V> e = (Entry<K,V>) tab[index];
tab[index] = new Entry<>(hash, key, value, e);
count++;
}
从代码结构上看得出,一共分为三部分,首先记录修改,然后检查是否超出了域值threshold需要rehash,最后根据参数创建Entry并添加在对应桶的表头。
- reconsititutionPut()
通用
-
isEmpty()
判断HashTable是否为空。 -
size()
返回HashTable中条目的数量。 -
clone()
-
toString
-
equals(Object)
-
hashCode()
-
forEach()
-
writeObject()
-
readObject()
-
computeIfAbsent
-
computeIfPresent()
-
compute
-
merge
增加
- put(K,V)
- putAll(Map<? extends K,? exntends V> t)
- putIfAbsent(K,V)
删除
- remove(Object)
- clear()
- remove(Object,Object)
修改
- replaceAll(BiFuntion)
- replace(K,V,V)
- replace(K,V)
查询
- contains(Object)
- containsKey(Object)
- containsValue(Object)
- get(Obejct)
- getOrDefault(Object,V)
视图
- keys()
- elements()
- getEnumeration(int)
根据 - getIterator(int)
- keySet()
- entrySet()
- values()