您的位置:首页 > 编程语言 > Java开发

从源码理解Hashtable.java

2016-05-11 20:11 471 查看
package java.util;

import java.io.*;
import java.util.concurrent.ThreadLocalRandom;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.function.BiFunction;

/**
* Hashtable实现了哈希表,把关键字映射到值,不允许空值null
* 作为关键字的对象必须实现hashCode和equals方法,以便从hashtable中存取对象
* 一个Hashtable对象有两个参数影响其性能:初始容量和装载因子。容量是哈希表中槽bucket的数目,初始容量只是创建时候的容量
* 哈希表对于哈希冲突是开放式的,一个槽中可能会存储多个Entry,遍历的时候只能顺序遍历。
* 装载因子用来衡量哈希表达到多满的程度的时候需要重新哈希,具体什么时候是否需要调用rehash方法还要看具体实现
* 通常默认的装载因子0.75提供了一个很好的时空取舍
* 初始容量控制了空间浪费与相当耗费时间的rehash操作的必要性之间的取舍。较大的初始容量可以保证不必rehash,但初始容量过大又容易浪费空间。
* 如果有很多Entry需要放进Hashtable,那就创建一个初始容量比较大的哈希表,比自动增长rehash的插入更加高效
* hashtable的使用例子:
*   Hashtable<String, Integer> numbers
*     = new Hashtable<String, Integer>();
*   numbers.put("one", 1);
*   numbers.put("two", 2);
*   numbers.put("three", 3);}
* 取数据的操作:
*   Integer n = numbers.get("two");
*   if (n != null) {
*     System.out.println("two = " + n);
*   }}
* 通过iterator方法返回的迭代器都是fail-fast的:如果迭代器创建之后hashtable发生除了通过迭代器自己的remove函数之外的结构改变,都会抛出ConcurrentModificationException异常
* Hashtable的keys和elements方法返回的枚举集合enumerator不是fail-fast的
*/
/**
* Hashtable继承于Dictionary,实现了Map、Cloneable、java.io.Serializable接口
* Hashtable的函数都是同步的,这意味着它是线程安全的。它的key、value都不可以为null。此外,Hashtable中的映射不是有序的。
* 涉及到结构改变的函数操作都使用synchronized修饰
*/
public class Hashtable<K,V>
extends Dictionary<K,V>
implements Map<K,V>, Cloneable, java.io.Serializable {

/**
* 哈希表中存放数据的地方.
*/
private transient Entry<?,?>[] table;

/**
* 哈希表中所有Entry的数目
*/
private transient int count;

/**
* 重新哈希的阈值(threshold = (int)capacity * loadFactor)
*/
private int threshold;

/**
* hashtable的装载因子
*/
private float loadFactor;

/**
* Hashtable的结构修改次数。结构修改指的是改变Entry数目或是修改内部结构(如rehash)
* 这个字段用来使Hashtable的集合视图fail-fast的。
*/
private transient int modCount = 0;

/** use serialVersionUID from JDK 1.0.2 for interoperability */
private static final long serialVersionUID = 1421746759512286392L;

/**
* 构造函数1:构造一个指定容量和装载因子的空哈希表
* @param      initialCapacity   the initial capacity of the hashtable.
* @param      loadFactor        the load factor of the hashtable.
* @exception  IllegalArgumentException  if the initial capacity is less
*             than zero, or if the load factor is nonpositive.
*/
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)Math.min(initialCapacity * loadFactor, MAX_ARRAY_SIZE + 1);
}

/**
* 构造函数2:构造一个指定容量的空哈希表,默认装载因子0.75
* @param     initialCapacity   the initial capacity of the hashtable.
* @exception IllegalArgumentException if the initial capacity is less
*              than zero.
*/
public Hashtable(int initialCapacity) {
this(initialCapacity, 0.75f);
}

/**
* 构造函数3:构造一个空哈希表,默认容量11,默认装载因子0.75
*/
public Hashtable() {
this(11, 0.75f);
}

/**
* 构造函数4:构造一个包含子Map的构造函数,容量为足够容纳指定Map中元素的2的次幂,默认装载因子0.75
* @param t the map whose mappings are to be placed in this map.
* @throws NullPointerException if the specified map is null.
*/
public Hashtable(Map<? extends K, ? extends V> t) {
this(Math.max(2*t.size(), 11), 0.75f);
putAll(t);
}

/**
* 返回Hashtable中键值对的数目,方法由synchronized修饰,支持同步调用
* @return  the number of keys in this hashtable.
*/
public synchronized int size() {
return count;
}

/**
* 测试Hashtable是否为空,方法由synchronized修饰,支持同步调用
* @return  <code>true</code> if this hashtable maps no keys to values;
*          <code>false</code> otherwise.
*/
public synchronized boolean isEmpty() {
return count == 0;
}

/**
* 返回Hashtable中所有关键字的一个枚举集合,方法由synchronized修饰,支持同步调用
* @return  an enumeration of the keys in this hashtable.
* @see     Enumeration
* @see     #elements()
* @see     #keySet()
* @see     Map
*/
public synchronized Enumeration<K> keys() {
return this.<K>getEnumeration(KEYS);
}

/**
* 返回Hashtable中所有值对象的枚举集合,使用返回对象的getEnumeration方法顺序获取元素
* @return  an enumeration of the values in this hashtable.
*/
public synchronized Enumeration<V> elements() {
return this.<V>getEnumeration(VALUES);
}

/**
* 测试Hashtable中是否有关键字映射到指定值上。contains(value)比containsKey(key)方法耗时多一些。
* 这个方法与Map接口containsValue方法功能相同
* @param      value   a value to search for
* @return     <code>true</code> if and only if some key maps to the
*             <code>value</code> argument in this hashtable as
*             determined by the <tt>equals</tt> method;
*             <code>false</code> otherwise.
* @exception  NullPointerException  if the value is <code>null</code>
*/
public synchronized boolean contains(Object value) {
//Hashtable中“键值对”的value不能使null,否则抛出异常NullPointerException
if (value == null) {
throw new NullPointerException();
}
//从后向前遍历table数组中的元素(Entry)
//对于每个Entry(单向链表),逐个遍历,判断结点的值是否等于value
Entry<?,?> tab[] = table;
for (int i = tab.length ; i-- > 0 ;) {
for (Entry<?,?> e = tab[i] ; e != null ; e = e.next) {
if (e.value.equals(value)) {
return true;
}
}
}
return false;
}

/**
* 与contains功能一样,本质就是调用了contains函数
* @param value value whose presence in this hashtable is to be tested
* @return <tt>true</tt> if this map maps one or more keys to the
*         specified value
* @throws NullPointerException  if the value is <code>null</code>
* @since 1.2
*/
public boolean containsValue(Object value) {
return contains(value);
}

/**
* 测试指定Key是否存在
* @param   key   possible key
* @return  <code>true</code> if and only if the specified object
*          is a key in this hashtable, as determined by the
*          <tt>equals</tt> method; <code>false</code> otherwise.
* @throws  NullPointerException  if the key is <code>null</code>
*/
public synchronized boolean containsKey(Object key) {
Entry<?,?> tab[] = table;
int hash = key.hashCode();
//关键字Key映射的哈希槽下标
int index = (hash & 0x7FFFFFFF) % tab.length;
//遍历链表找到与指定Key相等(equals)的元素
for (Entry<?,?> e = tab[index] ; e != null ; e = e.next) {
if ((e.hash == hash) && e.key.equals(key)) {
return true;
}
}
return false;
}

/**
* 返回指定关键字Key的value值,不存在则返回null
* @param key the key whose associated value is to be returned
* @return the value to which the specified key is mapped, or
*         {@code null} if this map contains no mapping for the key
* @throws NullPointerException if the specified key is null
* @see     #put(Object, Object)
*/
@SuppressWarnings("unchecked")
public synchronized V get(Object key) {
Entry<?,?> tab[] = table;
int hash = key.hashCode();
//计算指定关键字映射的哈希槽
int index = (hash & 0x7FFFFFFF) % tab.length;
//遍历单向链表
for (Entry<?,?> e = tab[index] ; e != null ; e = e.next) {
if ((e.hash == hash) && e.key.equals(key)) {
return (V)e.value;
}
}
return null;
}

/**
* 分配数组最大容量,一些虚拟机会保存数组的头字,试图分配更大的数组会导致OOM(OutOfMemoryError):请求的数组容量超出VM限制
*/
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

/**
* 容量增长时需要内部重新组织Hashtable,以更有效率的访问
* 当Hashtable中关键字数目超出容量与装载因子之积时,自动调用该方法
*/
@SuppressWarnings("unchecked")
protected void rehash() {
int oldCapacity = table.length;	//旧容量
Entry<?,?>[] oldMap = table;	//旧Entry数组

// 溢出检测(超出MAX_ARRAY_SIZE)
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数组
Entry<?,?>[] newMap = new Entry<?,?>[newCapacity];
//修改modCount
modCount++;
//修改新阈值(新阈值也不能超过MAX_ARRAY_SIZE)
threshold = (int)Math.min(newCapacity * loadFactor, MAX_ARRAY_SIZE + 1);
table = newMap;
//从后向前遍历旧表每一个槽中的链表的每一个Entry元素,将其重新哈希到新表中
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插入Index槽中当前链表的开头
e.next = (Entry<K,V>)newMap[index];
newMap[index] = e;
}
}
}
//添加新的Entry元素
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;
}
// 创建新的Entry,并插入Index槽中链表的头部
@SuppressWarnings("unchecked")
Entry<K,V> e = (Entry<K,V>) tab[index];
tab[index] = new Entry<>(hash, key, value, e);
count++;
}

/**
* 将指定的Key映射到指定的value。Key和value都不能为空null
* @param      key     the hashtable key
* @param      value   the value
* @return     the previous value of the specified key in this hashtable,
*             or <code>null</code> if it did not have one
* @exception  NullPointerException  if the key or value is
*               <code>null</code>
*/
public synchronized V put(K key, V value) {
// 确保value不为空null
if (value == null) {
throw new NullPointerException();
}
// 确保Key在Hashtable中不存在,若存在,更新value,并返回旧值
Entry<?,?> tab[] = table;
int hash = key.hashCode();
int index = (hash & 0x7FFFFFFF) % tab.length;
@SuppressWarnings("unchecked")
Entry<K,V> entry = (Entry<K,V>)tab[index];
for(; entry != null ; entry = entry.next) {
if ((entry.hash == hash) && entry.key.equals(key)) {
V old = entry.value;
entry.value = value;
return old;
}
}
//不存在,添加元素
addEntry(hash, key, value, index);
return null;
}

/**
* 删除关键字Key相关的Entry,如果不存在Key,就什么都不做(只是遍历一趟链表。。)
* @param   key   the key that needs to be removed
* @return  the value to which the key had been mapped in this hashtable,
*          or <code>null</code> if the key did not have a mapping
* @throws  NullPointerException  if the key is <code>null</code>
*/
public synchronized V remove(Object key) {
Entry<?,?> tab[] = table;
int hash = key.hashCode();
//获取下标Index
int index = (hash & 0x7FFFFFFF) % tab.length;
@SuppressWarnings("unchecked")
Entry<K,V> e = (Entry<K,V>)tab[index];
for(Entry<K,V> prev = null ; e != null ; prev = e, e = e.next) {
if ((e.hash == hash) && e.key.equals(key)) {
modCount++;
//删除e
if (prev != null) {
prev.next = e.next;
} else {
tab[index] = e.next;
}
count--;
V oldValue = e.value;
e.value = null;
//返回删除元素的value值
return oldValue;
}
}
return null;
}

/**
* 将指定Map中的所有映射都拷贝到Hashtable中,已经存在的Key对应的value值会被更新
* @param t mappings to be stored in this map
* @throws NullPointerException if the specified map is null
*/
public synchronized void putAll(Map<? extends K, ? extends V> t) {
for (Map.Entry<? extends K, ? extends V> e : t.entrySet())
put(e.getKey(), e.getValue());
}

/**
* 清空Hashtable,将Hashtable的table数组的值全部设为null
*/
public synchronized void clear() {
Entry<?,?> tab[] = table;
modCount++;
for (int index = tab.length; --index >= 0; )
tab[index] = null;
count = 0;
}

/**
* 创建一个Hashtable的浅拷贝。Hashtable自身的结构都被拷贝了(拷贝数组,拷贝链表),但是其中的关键字和值不拷贝(依然引用的同一份Key和value)。
* @return  a clone of the hashtable
*/
public synchronized Object clone() {
try {
Hashtable<?,?> t = (Hashtable<?,?>)super.clone();
t.table = new Entry<?,?>[table.length];
for (int i = table.length ; i-- > 0 ; ) {
//依次调用数组里的链表的第一个元素的clone方法,后继元素都自动复制了,因为clone中会调用后继元素的clone
t.table[i] = (table[i] != null)
? (Entry<?,?>) table[i].clone() : null;
}
t.keySet = null;
t.entrySet = null;
t.values = null;
t.modCount = 0;
return t;
} catch (CloneNotSupportedException e) {
// this shouldn't happen, since we are Cloneable
throw new InternalError(e);
}
}

/**
* 返回Hashtable对象的String表达方式,一系列以括号和逗号,空格分隔的Entry,如{key1=value1, key2=value2}
* @return  a string representation of this hashtable
*/
public synchronized String toString() {
int max = size() - 1;
//Hashtable中元素为空
if (max == -1)
return "{}";
//使用StringBuilder,提高字符串拼接效率
StringBuilder sb = new StringBuilder();
//获得Hashtable的Entry集合
Iterator<Map.Entry<K,V>> it = entrySet().iterator();

sb.append('{');
for (int i = 0; ; i++) {
Map.Entry<K,V> e = it.next();
K key = e.getKey();
V value = e.getValue();
sb.append(key   == this ? "(this Map)" : key.toString());
sb.append('=');
sb.append(value == this ? "(this Map)" : value.toString());

if (i == max)
return sb.append('}').toString();
sb.append(", ");
}
}

//获得指定类型(keys,values,entries)的枚举集合
private <T> Enumeration<T> getEnumeration(int type) {
if (count == 0) {
return Collections.emptyEnumeration();
} else {
//传false,新建枚举器
return new Enumerator<>(type, false);
}
}
//获得指定类型(keys,values,entries)的迭代器
private <T> Iterator<T> getIterator(int type) {
if (count == 0) {
return Collections.emptyIterator();
} else {
//传true参数,新建迭代器类型实例
return new Enumerator<>(type, true);
}
}

// 视图

/**
* 以下每个字段初始化后会包含一个首次请求后的指定视图,视图是无状态的,所以不必创建多个
*/
private transient volatile Set<K> keySet = null;
private transient volatile Set<Map.Entry<K,V>> entrySet = null;
private transient volatile Collection<V> values = null;

/**
* 返回Map的关键字视图Set,Map中的任何修改都会反映在Set中,反过来也是如此。当一个迭代器正在遍历时,如果Map的结构发生改变,迭代器行为未定义,
* 如果是使用迭代器的remove函数改变Map结构,不会发生异常
* set<K>支持Iterator.remove,Set.remove,removeAll,retainAll和clear函数
* 不支持add和addAll函数
*/
public Set<K> keySet() {
if (keySet == null)
//返回线程安全的KeySet
keySet = Collections.synchronizedSet(new KeySet(), this);
return keySet;
}
//KeySet类
private class KeySet extends AbstractSet<K> {
public Iterator<K> iterator() {
//返回关键字迭代器
return getIterator(KEYS);
}
public int size() {
return count;
}
public boolean contains(Object o) {
return containsKey(o);
}
public boolean remove(Object o) {
return Hashtable.this.remove(o) != null;
}
public void clear() {
Hashtable.this.clear();
}
}

/**
* 返回Map中映射的集合Set,Map中的改变会反映在Set中,反之亦是如此。
* 迭代器遍历Set时,如果Map结构发生变化,迭代器行为未定义,除了通过迭代器自身的remove操作和setValue操作
* 该Set支持通过Iterator.remove,Set.remove, removeAll, retainAll和clear操作删除元素
* 不支持add和addAll操作
*/
public Set<Map.Entry<K,V>> entrySet() {
if (entrySet==null)
//返回线程安全的entrySet
entrySet = Collections.synchronizedSet(new EntrySet(), this);
return entrySet;
}

private class EntrySet extends AbstractSet<Map.Entry<K,V>> {
public Iterator<Map.Entry<K,V>> iterator() {
//返回Entry的迭代器
return getIterator(ENTRIES);
}

public boolean add(Map.Entry<K,V> o) {
return super.add(o);
}

public boolean contains(Object o) {
//确定类型
if (!(o instanceof Map.Entry))
return false;
Map.Entry<?,?> entry = (Map.Entry<?,?>)o;
Object key = entry.getKey();
Entry<?,?>[] tab = table;
int hash = key.hashCode();
int index = (hash & 0x7FFFFFFF) % tab.length;

for (Entry<?,?> e = tab[index]; e != null; e = e.next)
//找到指定Entry
if (e.hash==hash && e.equals(entry))
return true;
return false;
}

public boolean remove(Object o) {
if (!(o instanceof Map.Entry))
return false;
Map.Entry<?,?> entry = (Map.Entry<?,?>) o;
Object key = entry.getKey();
Entry<?,?>[] tab = table;
int hash = key.hashCode();
//确定下标
int index = (hash & 0x7FFFFFFF) % tab.length;

@SuppressWarnings("unchecked")
Entry<K,V> e = (Entry<K,V>)tab[index];
for(Entry<K,V> prev = null; e != null; prev = e, e = e.next) {
if (e.hash==hash && e.equals(entry)) {
modCount++;
//删除找到的元素
if (prev != null)
prev.next = e.next;
else
tab[index] = e.next;

count--;
e.value = null;
return true;
}
}
return false;
}

public int size() {
return count;
}

public void clear() {
Hashtable.this.clear();
}
}

/**
* 返回Map中所有值的集合视图,Map中的任何修改都会反映在集合中,反之亦是如此。如果集合遍历过程中,Map发生结构上的修改,迭代行为未定义
* 除了通过迭代器自身的remove函数,集合支持元素删除,通过Iterator.remove,Collection.remove,removeAll,retainAll和clear等行为操作,
* 但不支持add和addAll操作
*/
public Collection<V> values() {
if (values==null)
//返回线程安全的值集合
values = Collections.synchronizedCollection(new ValueCollection(),
this);
return values;
}

private class ValueCollection extends AbstractCollection<V> {
public Iterator<V> iterator() {
//返回Values迭代器
return getIterator(VALUES);
}
public int size() {
return count;
}
public boolean contains(Object o) {
return containsValue(o);
}
public void clear() {
Hashtable.this.clear();
}
}

// 比较和哈希函数
/**
* 比较指定对象和当前Map,判断是否相等
* @param  o object to be compared for equality with this hashtable
* @return true if the specified Object is equal to this Map
*/
public synchronized boolean equals(Object o) {
//同一个元素,返回true
if (o == this)
return true;
//类型不同,直接否定
if (!(o instanceof Map))
return false;
Map<?,?> t = (Map<?,?>) o;
if (t.size() != size())
return false;

try {
//获取Entry的迭代器
Iterator<Map.Entry<K,V>> i = entrySet().iterator();
//判断Map中的每一个元素Entry的键值对是不是都在t中存在
while (i.hasNext()) {
Map.Entry<K,V> e = i.next();
K key = e.getKey();
V value = e.getValue();
//如果有不相等或是不存在的,立刻返回false
if (value == null) {
if (!(t.get(key)==null && t.containsKey(key)))
return false;
} else {
if (!value.equals(t.get(key)))
return false;
}
}
} catch (ClassCastException unused)   {
return false;
} catch (NullPointerException unused) {
return false;
}
return true;
}

/**
* 返回Map的哈希值,Map中每一个Entry的hashcode相加
* @see Map#hashCode()
*/
public synchronized int hashCode() {
/*
* 这段代码检测了由于哈希表自引用引起的递归计算,并阻止了栈溢出。
* 这段代码复用了装载因子loadFactor字段的功能,作为一个正在计算的标识位,为了节省空间。
* 装载因子为负说明正在计算hashcode
*/
int h = 0;
if (count == 0 || loadFactor < 0)
return h;  // 返回0

loadFactor = -loadFactor;  // Mark hashCode computation in progress
Entry<?,?>[] tab = table;
for (Entry<?,?> entry : tab) {
while (entry != null) {
//累加哈希值
h += entry.hashCode();
entry = entry.next;
}
}

loadFactor = -loadFactor;  // Mark hashCode computation complete
return h;
}

@Override
public synchronized V getOrDefault(Object key, V defaultValue) {
V result = get(key);
return (null == result) ? defaultValue : result;
}

@SuppressWarnings("unchecked")
@Override
public synchronized void forEach(BiConsumer<? super K, ? super V> action) {
Objects.requireNonNull(action);     // explicit check required in case
// table is empty.
final int expectedModCount = modCount;

Entry<?, ?>[] tab = table;
for (Entry<?, ?> entry : tab) {
while (entry != null) {
action.accept((K)entry.key, (V)entry.value);
entry = entry.next;

if (expectedModCount != modCount) {
throw new ConcurrentModificationException();
}
}
}
}

@SuppressWarnings("unchecked")
@Override
public synchronized void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
Objects.requireNonNull(function);     // explicit check required in case
// table is empty.
final int expectedModCount = modCount;

Entry<K, V>[] tab = (Entry<K, V>[])table;
for (Entry<K, V> entry : tab) {
while (entry != null) {
entry.value = Objects.requireNonNull(
function.apply(entry.key, entry.value));
entry = entry.next;

if (expectedModCount != modCount) {
throw new ConcurrentModificationException();
}
}
}
}
//存在Key就更新,不存在就添加
@Override
public synchronized V putIfAbsent(K key, V value) {
Objects.requireNonNull(value);	//检测value非空

// Makes sure the key is not already in the hashtable.
Entry<?,?> tab[] = table;
int hash = key.hashCode();
int index = (hash & 0x7FFFFFFF) % tab.length;
@SuppressWarnings("unchecked")
Entry<K,V> entry = (Entry<K,V>)tab[index];
for (; entry != null; entry = entry.next) {
if ((entry.hash == hash) && entry.key.equals(key)) {
V old = entry.value;
if (old == null) {
entry.value = value;
}
return old;
}
}

addEntry(hash, key, value, index);
return null;
}
//删除指定Key-value对
@Override
public synchronized boolean remove(Object key, Object value) {
Objects.requireNonNull(value);

Entry<?,?> tab[] = table;
int hash = key.hashCode();
int index = (hash & 0x7FFFFFFF) % tab.length;
@SuppressWarnings("unchecked")
Entry<K,V> e = (Entry<K,V>)tab[index];
for (Entry<K,V> prev = null; e != null; prev = e, e = e.next) {
if ((e.hash == hash) && e.key.equals(key) && e.value.equals(value)) {
modCount++;
if (prev != null) {
prev.next = e.next;
} else {
tab[index] = e.next;
}
count--;
e.value = null;
return true;
}
}
return false;
}
//替换旧值为新值,如果key对应的值不等于旧值(equals),就不替换
@Override
public synchronized boolean replace(K key, V oldValue, V newValue) {
Objects.requireNonNull(oldValue);
Objects.requireNonNull(newValue);
Entry<?,?> tab[] = table;
int hash = key.hashCode();
int index = (hash & 0x7FFFFFFF) % tab.length;
@SuppressWarnings("unchecked")
Entry<K,V> e = (Entry<K,V>)tab[index];
for (; e != null; e = e.next) {
if ((e.hash == hash) && e.key.equals(key)) {
if (e.value.equals(oldValue)) {
e.value = newValue;
return true;
} else {
return false;
}
}
}
return false;
}
//替换值,如果不存在key,返回null
@Override
public synchronized V replace(K key, V value) {
Objects.requireNonNull(value);
Entry<?,?> tab[] = table;
int hash = key.hashCode();
int index = (hash & 0x7FFFFFFF) % tab.length;
@SuppressWarnings("unchecked")
Entry<K,V> e = (Entry<K,V>)tab[index];
for (; e != null; e = e.next) {
if ((e.hash == hash) && e.key.equals(key)) {
V oldValue = e.value;
e.value = value;
return oldValue;
}
}
return null;
}
//如果不存在Key,就添加键值对key-value,value通过mappingFunction计算得到
@Override
public synchronized V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) {
Objects.requireNonNull(mappingFunction);

Entry<?,?> tab[] = table;
int hash = key.hashCode();
int index = (hash & 0x7FFFFFFF) % tab.length;
@SuppressWarnings("unchecked")
Entry<K,V> e = (Entry<K,V>)tab[index];
for (; e != null; e = e.next) {
if (e.hash == hash && e.key.equals(key)) {
// Hashtable not accept null value
return e.value;
}
}

V newValue = mappingFunction.apply(key);
if (newValue != null) {
addEntry(hash, key, newValue, index);
}

return newValue;
}

//如果存在就替换Key的value值,value通过mappingFunction计算得到,如果计算得到的value为null,就删除Key对应的Entry
@Override
public synchronized V computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
Objects.requireNonNull(remappingFunction);

Entry<?,?> tab[] = table;
int hash = key.hashCode();
int index = (hash & 0x7FFFFFFF) % tab.length;
@SuppressWarnings("unchecked")
Entry<K,V> e = (Entry<K,V>)tab[index];
for (Entry<K,V> prev = null; e != null; prev = e, e = e.next) {
if (e.hash == hash && e.key.equals(key)) {
V newValue = remappingFunction.apply(key, e.value);
//Hashtable不允许键值为null,删除Key对应的Entry
if (newValue == null) {
modCount++;
if (prev != null) {
prev.next = e.next;
} else {
tab[index] = e.next;
}
count--;
} else {
//不为空,替换为新值
e.value = newValue;
}
return newValue;
}
}
return null;
}

@Override
public synchronized V compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
Objects.requireNonNull(remappingFunction);

Entry<?,?> tab[] = table;
int hash = key.hashCode();
int index = (hash & 0x7FFFFFFF) % tab.length;
@SuppressWarnings("unchecked")
Entry<K,V> e = (Entry<K,V>)tab[index];
for (Entry<K,V> prev = null; e != null; prev = e, e = e.next) {
if (e.hash == hash && Objects.equals(e.key, key)) {
V newValue = remappingFunction.apply(key, e.value);
if (newValue == null) {
modCount++;
if (prev != null) {
prev.next = e.next;
} else {
tab[index] = e.next;
}
count--;
} else {
e.value = newValue;
}
return newValue;
}
}

V newValue = remappingFunction.apply(key, null);
if (newValue != null) {
addEntry(hash, key, newValue, index);
}

return newValue;
}

@Override
public synchronized V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
Objects.requireNonNull(remappingFunction);

Entry<?,?> tab[] = table;
int hash = key.hashCode();
int index = (hash & 0x7FFFFFFF) % tab.length;
@SuppressWarnings("unchecked")
Entry<K,V> e = (Entry<K,V>)tab[index];
for (Entry<K,V> prev = null; e != null; prev = e, e = e.next) {
if (e.hash == hash && e.key.equals(key)) {
V newValue = remappingFunction.apply(e.value, value);
if (newValue == null) {
modCount++;
if (prev != null) {
prev.next = e.next;
} else {
tab[index] = e.next;
}
count--;
} else {
e.value = newValue;
}
return newValue;
}
}

if (value != null) {
addEntry(hash, key, value, index);
}

return value;
}

/**
* 将Hashtable的状态保存进流中
* @serialData The <i>capacity</i> of the Hashtable (the length of the
*             bucket array) is emitted (int), followed by the
*             <i>size</i> of the Hashtable (the number of key-value
*             mappings), followed by the key (Object) and value (Object)
*             for each key-value mapping represented by the Hashtable
*             The key-value mappings are emitted in no particular order.
*/
private void writeObject(java.io.ObjectOutputStream s)
throws IOException {
Entry<Object, Object> entryStack = null;

synchronized (this) {
// Write out the length, threshold, loadfactor
s.defaultWriteObject();

// Write out length, count of elements
s.writeInt(table.length);
s.writeInt(count);

// Stack copies of the entries in the table
for (int index = 0; index < table.length; index++) {
Entry<?,?> entry = table[index];

while (entry != null) {
entryStack =
new Entry<>(0, entry.key, entry.value, entryStack);
entry = entry.next;
}
}
}

// Write out the key/value objects from the stacked entries
while (entryStack != null) {
s.writeObject(entryStack.key);
s.writeObject(entryStack.value);
entryStack = entryStack.next;
}
}

/**
* 从流中重建Hashtable(反序列化)
*/
private void readObject(java.io.ObjectInputStream s)
throws IOException, ClassNotFoundException
{
// Read in the length, threshold, and loadfactor
s.defaultReadObject();

// Read the original length of the array and number of elements
int origlength = s.readInt();
int elements = s.readInt();

// Compute new size with a bit of room 5% to grow but
// no larger than the original size.  Make the length
// odd if it's large enough, this helps distribute the entries.
// Guard against the length ending up zero, that's not valid.
int length = (int)(elements * loadFactor) + (elements / 20) + 3;
if (length > elements && (length & 1) == 0)
length--;
if (origlength > 0 && length > origlength)
length = origlength;
table = new Entry<?,?>[length];
threshold = (int)Math.min(length * loadFactor, MAX_ARRAY_SIZE + 1);
count = 0;

// Read the number of elements and then all the key/value objects
for (; elements > 0; elements--) {
@SuppressWarnings("unchecked")
K key = (K)s.readObject();
@SuppressWarnings("unchecked")
V value = (V)s.readObject();
// synch could be eliminated for performance
reconstitutionPut(table, key, value);
}
}

/**
* readObject使用的put方法(重建put),因为put方法支持重写,并且子类尚未初始化的时候不能调用put方法,所以就提供了reconstitutionPut
* 它和常规put方法有几点不同,不检测rehash,因为初始元素数目已知。modCount不会自增,因为我们是在创建一个新的实例。
* 不需要返回值
*/
private void reconstitutionPut(Entry<?,?>[] tab, K key, V value)
throws StreamCorruptedException
{
if (value == null) {
throw new java.io.StreamCorruptedException();
}
// 确保Key不在Hashtable中
// 反序列化过程中不应该 会发生的情况
int hash = key.hashCode();
int index = (hash & 0x7FFFFFFF) % tab.length;
for (Entry<?,?> e = tab[index] ; e != null ; e = e.next) {
//反序列化过程中如果出现Key值重复,抛出异常StreamCorruptedException
if ((e.hash == hash) && e.key.equals(key)) {
throw new java.io.StreamCorruptedException();
}
}
// 创建新的Entry.
@SuppressWarnings("unchecked")
Entry<K,V> e = (Entry<K,V>)tab[index];
tab[index] = new Entry<>(hash, key, value, e);
count++;
}

/**
* Hashtable使用单向链表Entry解决哈希冲突
*/
private static class Entry<K,V> implements Map.Entry<K,V> {
final int hash;	//哈希值,不可变
final K key;	//关键字,不可变
V value;		//值,可变
Entry<K,V> next;

protected Entry(int hash, K key, V value, Entry<K,V> next) {
this.hash = hash;
this.key =  key;
this.value = value;
this.next = next;
}
//返回一个自身的复制对象,浅拷贝,因为还是引用的当前key和value对象,没有新建key和value对象
@SuppressWarnings("unchecked")
protected Object clone() {
return new Entry<>(hash, key, value,
(next==null ? null : (Entry<K,V>) next.clone()));
}
// Map.Entry 操作
public K getKey() {
return key;
}

public V getValue() {
return value;
}

public V setValue(V value) {
//Hashtable不允许空null值
if (value == null)
throw new NullPointerException();

V oldValue = this.value;
this.value = value;
//返回原值
return oldValue;
}
//重写equals方法
public boolean equals(Object o) {
if (!(o instanceof Map.Entry))
return false;
Map.Entry<?,?> e = (Map.Entry<?,?>)o;
//类型相同且键值(key-value)也相同(equals返回true)
return (key==null ? e.getKey()==null : key.equals(e.getKey())) &&
(value==null ? e.getValue()==null : value.equals(e.getValue()));
}

public int hashCode() {
//hash值只与关键字key有关,hashCode需要与值value的hashCode异或
return hash ^ Objects.hashCode(value);
}

public String toString() {
return key.toString()+"="+value.toString();
}
}

// Enumerations/Iterations的类型
private static final int KEYS = 0;
private static final int VALUES = 1;
private static final int ENTRIES = 2;

/**
* Hashtable的枚举类。实现了迭代器和枚举接口,但是去掉迭代器方法也能单独创建实例
* 这对于避免只通过传递枚举类型来提升容量的意外情况很重要
*/
private class Enumerator<T> implements Enumeration<T>, Iterator<T> {
Entry<?,?>[] table = Hashtable.this.table;	//由Hashtable的table数组支持
int index = table.length;		//table数组的长度
Entry<?,?> entry = null;		//下一个返回元素
Entry<?,?> lastReturned = null;	//上一次返回元素
int type;	//类型:KEYS,Values,Entries

/**
* 表明当前枚举是作为一个迭代器还是一个枚举类型(true表示迭代器)
*/
boolean iterator;

/**
* 迭代器认为Hashtable应该拥有的modCount值。如果期望的不一致,迭代器就检测到并发修改了
*/
protected int expectedModCount = modCount;
/**
* 构造函数:构造一个类型为type的迭代器或枚举集合(iterator为true表示迭代器)
* @param type
* @param iterator
*/
Enumerator(int type, boolean iterator) {
this.type = type;
this.iterator = iterator;
}
//是否还有更多元素
public boolean hasMoreElements() {
Entry<?,?> e = entry;
int i = index;
Entry<?,?>[] t = table;
/* 使用本地变量可以使迭代循环的更快*/
//上一个返回元素为空,表明从头开始返回
while (e == null && i > 0) {
//table数组从后向前遍历,找到第一个非空元素
e = t[--i];
}
entry = e;
index = i;
return e != null;
}
//返回下一个元素
@SuppressWarnings("unchecked")
public T nextElement() {
Entry<?,?> et = entry;
int i = index;
Entry<?,?>[] t = table;
/* 使用本地变量可以使循环迭代得更快 */
//上一个返回元素为空,表明开始返回第一个元素
while (et == null && i > 0) {
//table数组从后向前遍历,找到第一个非空元素
et = t[--i];
}
entry = et;
index = i;	//更新Index为当前返回的最大i
if (et != null) {
Entry<?,?> e = lastReturned = entry;	//更新上一个返回元素为当前即将返回的元素
entry = e.next;		//更新下一个返回元素为e.next
//类型为keys则返回Key,为value则返回value,否则返回Entry
return type == KEYS ? (T)e.key : (type == VALUES ? (T)e.value : (T)e);
}
//抛出找不到元素异常
throw new NoSuchElementException("Hashtable Enumerator");
}

// 迭代器方法
public boolean hasNext() {
return hasMoreElements();
}
//返回下一个元素
public T next() {
//首先检测并发修改异常
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
//调用nextElement方法
return nextElement();
}
//删除函数,删除的是上一个返回元素lastReturned
public void remove() {
//只有迭代器类型支持该函数 ,否则抛出不支持该操作异常UnsupportedOperationException()
if (!iterator)
throw new UnsupportedOperationException();
//如果上一个返回元素为空,抛出非法状态异常IllegalStateException
if (lastReturned == null)
throw new IllegalStateException("Hashtable Enumerator");
//检测并发修改异常ConcurrentModificationException
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
//删除时,需要锁住全表
synchronized(Hashtable.this) {
Entry<?,?>[] tab = Hashtable.this.table;
//上一个返回元素的哈希值最高位之外的所有位模table的长度
int index = (lastReturned.hash & 0x7FFFFFFF) % tab.length;

@SuppressWarnings("unchecked")
//获取该槽位第一个元素
Entry<K,V> e = (Entry<K,V>)tab[index];
//从单链表的一端向后遍历
for(Entry<K,V> prev = null; e != null; prev = e, e = e.next) {
//当前元素即为上一个返回元素
if (e == lastReturned) {
modCount++;
expectedModCount++;
//删除上一个元素
if (prev == null)
tab[index] = e.next;
else
prev.next = e.next;
count--;
lastReturned = null;
return;
}
}
throw new ConcurrentModificationException();
}
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: