HaspMap分析

Hashmap(先沾上,有空具体分析)

public class HashMap<K,V> extends AbstractMap<K,V>
    implements Map<K,V>, Cloneable, Serializable {
	private static final long serialVersionUID = 362498820763181265L;
	/**
     * 默认容量为2的幂
     */
	static final int DEFAULT_INITIAL_CAPACITY = 1 << 4;
	// aka 16
	/**
     * 最大容量2的29次方
     */
	static final int MAXIMUM_CAPACITY = 1 << 30;
	/**
     * 加载因子0.75,既保证不经常扩充容量,又保证容器的使用效率
     */
	static final float DEFAULT_LOAD_FACTOR = 0.75f;
	/**
     * 当同一位置的元素数量大于8时转变为树形结构储存,而不是链表
     */
	static final int TREEIFY_THRESHOLD = 8;
	/**
     * 当同一位置的元素数量小于6时,树形结构转变为链表储存
     */
	static final int UNTREEIFY_THRESHOLD = 6;
	/**
     * 容器容量为64以上,时才进行树形化结构的变化,防止出现扩容和树形化的冲突
     */
	static final int MIN_TREEIFY_CAPACITY = 64;
	/**
     * 节点继承了词条Map.Entry<K,V>,有哈希值、键、值、下一个节点四个属性
     */
	static class Node<K,V> implements Map.Entry<K,V> {
		final int hash;
		final K key;
		V value;
		Node<K,V> next;
		Node(int hash, K key, V value, Node<K,V> next) {
			this.hash = hash;
			this.key = key;
			this.value = value;
			this.next = next;
		}
		public final K getKey()        {
			return key;
		}
		public final V getValue()      {
			return value;
		}
		public final String toString() {
			return key + "=" + value;
		}
		public final int hashCode() {
			return Objects.hashCode(key) ^ Objects.hashCode(value);
		}
		public final V setValue(V newValue) {
			V oldValue = value;
			value = newValue;
			return oldValue;
		}
		public final Boolean equals(Object o) {
			if (o == this)
			                return true;
			if (o instanceof Map.Entry) {
				Map.Entry<?,?> e = (Map.Entry<?,?>)o;
				if (Objects.equals(key, e.getKey()) &&
				                    Objects.equals(value, e.getValue()))
				                    return true;
			}
			return false;
		}
	}
	/**
     * key的哈希值,有32位,一般来说只有后四位才有作用(取余),为了降低冲突的可能性
	 * 将哈希值右移16位,并用异或运算符得到最终的值
     */
	static final int hash(Object key) {
		int h;
		return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
	}
	/**
     * 表的容量
     */
	static final int tableSizeFor(int cap) {
		int n = cap - 1;
		n |= n >>> 1;
		n |= n >>> 2;
		n |= n >>> 4;
		n |= n >>> 8;
		n |= n >>> 16;
		return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
	}
	/**
	*表的一些属性
	*/
	transient Node<K,V>[] table;
	transient Set<Map.Entry<K,V>> entrySet;
	transient int size;
	transient int modCount;
	int threshold;
	final float loadFactor;
	/* ---------------- 构造器 -------------- */
	/**
     * 带有容量和加载因子的构造器
     */
	public HashMap(int initialCapacity, float loadFactor) {
		if (initialCapacity < 0)
		            throw new IllegalArgumentException("Illegal initial capacity: " +
		                                               initialCapacity);
		if (initialCapacity > MAXIMUM_CAPACITY)
		            initialCapacity = MAXIMUM_CAPACITY;
		if (loadFactor <= 0 || float.isNaN(loadFactor))
		            throw new IllegalArgumentException("Illegal load factor: " +
		                                               loadFactor);
		this.loadFactor = loadFactor;
		this.threshold = tableSizeFor(initialCapacity);
	}
	/**
     * 带有容量的构造器,加载因子默认0.75
     */
	public HashMap(int initialCapacity) {
		this(initialCapacity, DEFAULT_LOAD_FACTOR);
	}
	/**
     * 构造器,加载因子默认0.75,容量16
     */
	public HashMap() {
		this.loadFactor = DEFAULT_LOAD_FACTOR;
	}
	/**
     * 带有映射的构造器,加载因子0.75,将映射的数据加载到HashMap中
     */
	public HashMap(Map<? extends K, ? extends V> m) {
		this.loadFactor = DEFAULT_LOAD_FACTOR;
		putMapEntries(m, false);
	}
	/**
     * 相关方法
     */
	final void putMapEntries(Map<? extends K, ? extends V> m, Boolean evict) {
		int s = m.size();
		if (s > 0) {
			if (table == null) {
				//容器位空
				float ft = ((float)s / loadFactor) + 1.0F;
				int t = ((ft < (float)MAXIMUM_CAPACITY) ?
				                         (int)ft : MAXIMUM_CAPACITY);
				if (t > threshold)
				                    threshold = tableSizeFor(t);
			} else if (s > threshold)//数据量大于扩容阈值,调用resize()扩容
			resize();
			for (Map.Entry<? extends K, ? extends V> e : m.entrySet()) {
				//加载数据
				K key = e.getKey();
				V value = e.getValue();
				putVal(hash(key), key, value, false, evict);
			}
		}
	}
	/**
     * 通过哈希值和键得到值
     */
	final Node<K,V> getNode(int hash, Object key) {
		Node<K,V>[] tab;
		Node<K,V> first, e;
		int n;
		K k;
		if ((tab = table) != null && (n = tab.length) > 0 &&
		            (first = tab[(n - 1) & hash]) != null) {
			if (first.hash == hash && // 检测该位置位于表中的数据是否复合
			((k = first.key) == key || (key != null && key.equals(k))))
			                return first;
			if ((e = first.next) != null) {
				//检测位于链表或树中的数据
				if (first instanceof TreeNode)//判断储存的结构类型
				return ((TreeNode<K,V>)first).getTreeNode(hash, key);
				do {
					if (e.hash == hash &&
					                        ((k = e.key) == key || (key != null && key.equals(k))))
					                        return e;
				}
				while ((e = e.next) != null);
			}
		}
		return null;
	}
	/**
     * 将哈希值和键已知的位置处,添加一个值
     */
	final V putVal(int hash, K key, V value, Boolean onlyIfAbsent,
	                   Boolean evict) {
		Node<K,V>[] tab;
		Node<K,V> p;
		int n, i;
		if ((tab = table) == null || (n = tab.length) == 0)//表为空时
		n = (tab = resize()).length;
		//初始化,容量为16,扩容阈值12
		if ((p = tab[i = (n - 1) & hash]) == null)//该位置的数据为空
		tab[i] = newNode(hash, key, value, null);
		//储存数据 else {
			//该位置处有值
			Node<K,V> e;
			K k;
			if (p.hash == hash &&//key和哈希值相等的情况
			((k = p.key) == key || (key != null && key.equals(k))))
			                e = p; else if (p instanceof TreeNode)//不相等,树形结构
			e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value); else {
				//链表结构
				for (int binCount = 0; ; ++binCount) {
					if ((e = p.next) == null) {
						p.next = newNode(hash, key, value, null);
						if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
						treeifyBin(tab, hash);
						break;
					}
					if (e.hash == hash &&
					                        ((k = e.key) == key || (key != null && key.equals(k))))
					                        break;
					p = e;
				}
			}
			if (e != null) {
				// e不为空
				V oldValue = e.value;
				if (!onlyIfAbsent || oldValue == null)
				                    e.value = value;
				//覆盖值
				afterNodeAccess(e);
				return oldValue;
				//返回e的值
			}
		}
		++modCount;
		if (++size > threshold)
		            resize();
		afterNodeInsertion(evict);
		//这个不同清楚
		return null;
	}
	/**
     * 对容量进行重新设定,扩容
     */
	final Node<K,V>[] resize() {
		Node<K,V>[] oldTab = table;
		int oldCap = (oldTab == null) ? 0 : oldTab.length;
		int oldThr = threshold;
		int newCap, newThr = 0;
		if (oldCap > 0) {
			if (oldCap >= MAXIMUM_CAPACITY) {
				threshold = Integer.MAX_VALUE;
				return oldTab;
				//已经最大,无法扩容,返回原表
			} else if ((newCap = oldCap << 1) < MAXIMUM_CAPACITY &&//容量增加一倍并进行情况的分析
			oldCap >= DEFAULT_INITIAL_CAPACITY)
			                newThr = oldThr << 1;
			// 新的扩容阈值增加一倍
		} else if (oldThr > 0) //原先容量为0,原先扩容阈值大于0
		newCap = oldThr;
		//将扩容阈值赋给新容量 else {
			//设置默认容量16,扩容阈值12
			newCap = DEFAULT_INITIAL_CAPACITY;
			newThr = (int)(DEFAULT_LOAD_FACTOR * DEFAULT_INITIAL_CAPACITY);
		}
		if (newThr == 0) {
			//上述情况二
			float ft = (float)newCap * loadFactor;
			//设置扩容阈值
			newThr = (newCap < MAXIMUM_CAPACITY && ft < (float)MAXIMUM_CAPACITY ?
			                      (int)ft : Integer.MAX_VALUE);
		}
		threshold = newThr;
		@SuppressWarnings({
			"rawtypes","unchecked"
		}
		)
		            Node<K,V>[] newTab = (Node<K,V>[])new Node[newCap];
		table = newTab;
		if (oldTab != null) {
			for (int j = 0; j < oldCap; ++j) {
				Node<K,V> e;
				if ((e = oldTab[j]) != null) {
					oldTab[j] = null;
					//清空原先的表
					if (e.next == null)//没有相邻节点
					newTab[e.hash & (newCap - 1)] = e; else if (e instanceof TreeNode)//二叉树
					((TreeNode<K,V>)e).split(this, newTab, j, oldCap); else {
						// 链表
						Node<K,V> loHead = null, loTail = null;
						//还处于原来的位置
						Node<K,V> hiHead = null, hiTail = null;
						//不处于原来的位置
						Node<K,V> next;
						do {
							next = e.next;
							if ((e.hash & oldCap) == 0) {
								//e的哈希值与老的容量的取余为0
								if (loTail == null)//空的情况下
								loHead = e;
								//赋予e else
								                                    loTail.next = e;
								//不空的情况,赋予该位置链表的尾端
								loTail = e;
								//最终链表尾端为e
							} else {
								if (hiTail == null)
								                                    hiHead = e; else
								                                    hiTail.next = e;
								hiTail = e;
							}
						}
						while ((e = next) != null);
						if (loTail != null) {
							loTail.next = null;
							newTab[j] = loHead;
						}
						if (hiTail != null) {
							hiTail.next = null;
							newTab[j + oldCap] = hiHead;
						}
					}
				}
			}
		}
		return newTab;
	}
	/**
     * 转变为二叉树结构
     */
	final void treeifyBin(Node<K,V>[] tab, int hash) {
		int n, index;
		Node<K,V> e;
		if (tab == null || (n = tab.length) < MIN_TREEIFY_CAPACITY)//如果表为空或表长小于最小容量
		resize();
		//重新改变容量 else if ((e = tab[index = (n - 1) & hash]) != null) {
			//如果表的最后一个位置不为空
			TreeNode<K,V> hd = null, tl = null;
			//设置一头一尾
			do {
				TreeNode<K,V> p = replacementTreeNode(e, null);
				//新建一个树节点
				if (tl == null)//判断页节点是否为空
				hd = p; else {
					//不为空
					p.prev = tl;
					tl.next = p;
				}
				tl = p;
				//设置为叶节点
			}
			while ((e = e.next) != null);
			if ((tab[index] = hd) != null)
			                hd.treeify(tab);
			//形成与此节点链接的节点树
		}
	}
	public V remove(Object key) {
		Node<K,V> e;
		return (e = removeNode(hash(key), key, null, false, true)) == null ?
		            null : e.value;
	}
	/**
     * 移除节点
     */
	final Node<K,V> removeNode(int hash, Object key, Object value,
	                               Boolean matchValue, Boolean movable) {
		Node<K,V>[] tab;
		Node<K,V> p;
		int n, index;
		if ((tab = table) != null && (n = tab.length) > 0 &&
		            (p = tab[index = (n - 1) & hash]) != null) {
			//表中各位置都有数据
			Node<K,V> node = null, e;
			K k;
			V v;
			if (p.hash == hash &&//如果p的哈希值和键与要删除的完全相同
			((k = p.key) == key || (key != null && key.equals(k))))
			                node = p; else if ((e = p.next) != null) {
				if (p instanceof TreeNode)//二叉树结构
				node = ((TreeNode<K,V>)p).getTreeNode(hash, key); else {
					//链表结构
					do {
						if (e.hash == hash &&
						                            ((k = e.key) == key ||
						                             (key != null && key.equals(k)))) {
							node = e;
							break;
						}
						p = e;
					}
					while ((e = e.next) != null);
					//直到找到完全相等的值,或得知没有该对应的值
				}
			}
			if (node != null && (!matchValue || (v = node.value) == value ||
			                                 (value != null && value.equals(v)))) {
				//确认找到完全对应的值
				if (node instanceof TreeNode)//树形结构
				((TreeNode<K,V>)node).removeTreeNode(this, tab, movable); else if (node == p)//在表中位置上
				tab[index] = node.next; else//在表的链表上
				p.next = node.next;
				++modCount;
				--size;
				afterNodeRemoval(node);
				return node;
			}
		}
		return null;
	}
	/**
     * 键的集合与方法
     */
	public Set<K> keySet() {
		Set<K> ks = keySet;
		if (ks == null) {
			ks = new KeySet();
			keySet = ks;
		}
		return ks;
	}
	final class KeySet extends AbstractSet<K> {
		public final int size()                 {
			return size;
		}
		public final void clear()               {
			HashMap.this.clear();
		}
		public final Iterator<K> iterator()     {
			return new KeyIterator();
		}
		public final Boolean contains(Object o) {
			return containsKey(o);
		}
		public final Boolean remove(Object key) {
			return removeNode(hash(key), key, null, false, true) != null;
		}
		public final Spliterator<K> spliterator() {
			return new KeySpliterator<>(HashMap.this, 0, -1, 0, 0);
		}
		public final void forEach(Consumer<? super K> action) {
			Node<K,V>[] tab;
			if (action == null)
			                throw new NullPointerException();
			if (size > 0 && (tab = table) != null) {
				int mc = modCount;
				for (int i = 0; i < tab.length; ++i) {
					for (Node<K,V> e = tab[i]; e != null; e = e.next)
					                        action.accept(e.key);
				}
				if (modCount != mc)
				                    throw new ConcurrentModificationException();
			}
		}
	}
	/**
     * 值的集合与方法
     */
	public Collection<V> values() {
		Collection<V> vs = values;
		if (vs == null) {
			vs = new Values();
			values = vs;
		}
		return vs;
	}
	final class Values extends AbstractCollection<V> {
		public final int size()                 {
			return size;
		}
		public final void clear()               {
			HashMap.this.clear();
		}
		public final Iterator<V> iterator()     {
			return new ValueIterator();
		}
		public final Boolean contains(Object o) {
			return containsValue(o);
		}
		public final Spliterator<V> spliterator() {
			return new ValueSpliterator<>(HashMap.this, 0, -1, 0, 0);
		}
		public final void forEach(Consumer<? super V> action) {
			Node<K,V>[] tab;
			if (action == null)
			                throw new NullPointerException();
			if (size > 0 && (tab = table) != null) {
				int mc = modCount;
				for (int i = 0; i < tab.length; ++i) {
					for (Node<K,V> e = tab[i]; e != null; e = e.next)
					                        action.accept(e.value);
				}
				if (modCount != mc)
				                    throw new ConcurrentModificationException();
			}
		}
	}
	/**
     * 词条的集合与方法
     */
	public Set<Map.Entry<K,V>> entrySet() {
		Set<Map.Entry<K,V>> es;
		return (es = entrySet) == null ? (entrySet = new EntrySet()) : es;
	}
	final class EntrySet extends AbstractSet<Map.Entry<K,V>> {
		public final int size()                 {
			return size;
		}
		public final void clear()               {
			HashMap.this.clear();
		}
		public final Iterator<Map.Entry<K,V>> iterator() {
			return new EntryIterator();
		}
		public final Boolean contains(Object o) {
			if (!(o instanceof Map.Entry))
			                return false;
			Map.Entry<?,?> e = (Map.Entry<?,?>) o;
			Object key = e.getKey();
			Node<K,V> candidate = getNode(hash(key), key);
			return candidate != null && candidate.equals(e);
		}
		public final Boolean remove(Object o) {
			if (o instanceof Map.Entry) {
				Map.Entry<?,?> e = (Map.Entry<?,?>) o;
				Object key = e.getKey();
				Object value = e.getValue();
				return removeNode(hash(key), key, value, true, true) != null;
			}
			return false;
		}
		public final Spliterator<Map.Entry<K,V>> spliterator() {
			return new EntrySpliterator<>(HashMap.this, 0, -1, 0, 0);
		}
		public final void forEach(Consumer<? super Map.Entry<K,V>> action) {
			Node<K,V>[] tab;
			if (action == null)
			                throw new NullPointerException();
			if (size > 0 && (tab = table) != null) {
				int mc = modCount;
				for (int i = 0; i < tab.length; ++i) {
					for (Node<K,V> e = tab[i]; e != null; e = e.next)
					                        action.accept(e);
				}
				if (modCount != mc)
				                    throw new ConcurrentModificationException();
			}
		}
	}
	// jdk8增加的方法
	@Override
	    public V getOrDefault(Object key, V defaultValue) {
		Node<K,V> e;
		return (e = getNode(hash(key), key)) == null ? defaultValue : e.value;
	}
	@Override
	    public V putIfAbsent(K key, V value) {
		return putVal(hash(key), key, value, true, true);
	}
	@Override
	    public Boolean remove(Object key, Object value) {
		return removeNode(hash(key), key, value, true, true) != null;
	}
	@Override
	    public Boolean replace(K key, V oldValue, V newValue) {
		Node<K,V> e;
		V v;
		if ((e = getNode(hash(key), key)) != null &&
		            ((v = e.value) == oldValue || (v != null && v.equals(oldValue)))) {
			e.value = newValue;
			afterNodeAccess(e);
			return true;
		}
		return false;
	}
	@Override
	    public V replace(K key, V value) {
		Node<K,V> e;
		if ((e = getNode(hash(key), key)) != null) {
			V oldValue = e.value;
			e.value = value;
			afterNodeAccess(e);
			return oldValue;
		}
		return null;
	}
	@Override
	    public V computeIfAbsent(K key,
	                             Function<? super K, ? extends V> mappingFunction) {
		if (mappingFunction == null)
		            throw new NullPointerException();
		int hash = hash(key);
		Node<K,V>[] tab;
		Node<K,V> first;
		int n, i;
		int binCount = 0;
		TreeNode<K,V> t = null;
		Node<K,V> old = null;
		if (size > threshold || (tab = table) == null ||
		            (n = tab.length) == 0)//如果数量过多或过少,要对容器进行大小改变
		n = (tab = resize()).length;
		if ((first = tab[i = (n - 1) & hash]) != null) {
			//找到对应的位置处,不为空
			if (first instanceof TreeNode)//树形结构
			old = (t = (TreeNode<K,V>)first).getTreeNode(hash, key); else {
				//链表结构
				Node<K,V> e = first;
				K k;
				do {
					if (e.hash == hash &&
					                        ((k = e.key) == key || (key != null && key.equals(k)))) {
						old = e;
						break;
					}
					++binCount;
				}
				while ((e = e.next) != null);
			}
			V oldValue;
			if (old != null && (oldValue = old.value) != null) {
				//完全相同
				afterNodeAccess(old);
				return oldValue;
			}
		}
		V v = mappingFunction.apply(key);
		//得到V
		if (v == null) {
			//为空
			return null;
		} else if (old != null) {
			//覆盖原值并返回
			old.value = v;
			afterNodeAccess(old);
			return v;
		} else if (t != null)//未找到对应值
		t.putTreeVal(this, tab, hash, key, v);
		//树形结构 else {
			//链表
			tab[i] = newNode(hash, key, v, first);
			//判断是否进行变化
			if (binCount >= TREEIFY_THRESHOLD - 1)
			                treeifyBin(tab, hash);
		}
		++modCount;
		++size;
		afterNodeInsertion(true);
		return v;
		//返回值
	}
	/**
	* 遍历
	*/
	@Override
	    public void forEach(BiConsumer<? super K, ? super V> action) {
		Node<K,V>[] tab;
		if (action == null)
		            throw new NullPointerException();
		if (size > 0 && (tab = table) != null) {
			int mc = modCount;
			for (int i = 0; i < tab.length; ++i) {
				for (Node<K,V> e = tab[i]; e != null; e = e.next)
				                    action.accept(e.key, e.value);
			}
			if (modCount != mc)//防止出现其他进程改变
			throw new ConcurrentModificationException();
		}
	}
	/**
     * 克隆,键和值本身没有拷贝
     */
	@SuppressWarnings("unchecked")
	    @Override
	    public Object clone() {
		HashMap<K,V> result;
		try {
			result = (HashMap<K,V>)super.clone();
		}
		catch (CloneNotSupportedException e) {
			// this shouldn't happen, since we are Cloneable
			throw new InternalError(e);
		}
		result.reinitialize();
		result.putMapEntries(this, false);
		return result;
	}
	/* ---------------------迭代器--------------------------------------- */
	abstract class HashIterator {
		Node<K,V> next;
		// next entry to return
		Node<K,V> current;
		// current entry
		int expectedModCount;
		// for fast-fail
		int index;
		// current slot
		HashIterator() {
			expectedModCount = modCount;
			Node<K,V>[] t = table;
			current = next = null;
			index = 0;
			if (t != null && size > 0) {
				// advance to first entry
				do {
				}
				while (index < t.length && (next = t[index++]) == null);
			}
		}
		public final Boolean hasNext() {
			return next != null;
		}
		final Node<K,V> nextNode() {
			Node<K,V>[] t;
			Node<K,V> e = next;
			if (modCount != expectedModCount)
			                throw new ConcurrentModificationException();
			if (e == null)
			                throw new NoSuchElementException();
			if ((next = (current = e).next) == null && (t = table) != null) {
				do {
				}
				while (index < t.length && (next = t[index++]) == null);
			}
			return e;
		}
		public final void remove() {
			Node<K,V> p = current;
			if (p == null)
			                throw new IllegalStateException();
			if (modCount != expectedModCount)
			                throw new ConcurrentModificationException();
			current = null;
			K key = p.key;
			removeNode(hash(key), key, null, false, false);
			expectedModCount = modCount;
		}
	}
	final class KeyIterator extends HashIterator
	        implements Iterator<K> {
		public final K next() {
			return nextNode().key;
		}
	}
	final class ValueIterator extends HashIterator
	        implements Iterator<V> {
		public final V next() {
			return nextNode().value;
		}
	}
	final class EntryIterator extends HashIterator
	        implements Iterator<Map.Entry<K,V>> {
		public final Map.Entry<K,V> next() {
			return nextNode();
		}
	}
	/* ---------------------------分裂--------------------------------- */
	//https://blog.csdn.net/sawiii/article/details/100068823
	/**
	*树形结构
	*
	*/
	static final class TreeNode<K,V> extends LinkedHashMap.Entry<K,V> {
		TreeNode<K,V> parent;
		// red-black tree links
		TreeNode<K,V> left;
		TreeNode<K,V> right;
		TreeNode<K,V> prev;
		// needed to unlink next upon deletion
		Boolean red;
		TreeNode(int hash, K key, V val, Node<K,V> next) {
			super(hash, key, val, next);
		}
		/**
         * Returns root of tree containing this node.
         */
		final TreeNode<K,V> root() {
			for (TreeNode<K,V> r = this, p;;) {
				if ((p = r.parent) == null)
				                    return r;
				r = p;
			}
		}
		/**
         * Ensures that the given root is the first node of its bin.
         */
		static <K,V> void moveRootToFront(Node<K,V>[] tab, TreeNode<K,V> root) {
			int n;
			if (root != null && tab != null && (n = tab.length) > 0) {
				int index = (n - 1) & root.hash;
				TreeNode<K,V> first = (TreeNode<K,V>)tab[index];
				if (root != first) {
					Node<K,V> rn;
					tab[index] = root;
					TreeNode<K,V> rp = root.prev;
					if ((rn = root.next) != null)
					                        ((TreeNode<K,V>)rn).prev = rp;
					if (rp != null)
					                        rp.next = rn;
					if (first != null)
					                        first.prev = root;
					root.next = first;
					root.prev = null;
				}
				assert checkInvariants(root);
			}
		}
		/**
         * Finds the node starting at root p with the given hash and key.
         * The kc argument caches comparableClassFor(key) upon first use
         * comparing keys.
         */
		final TreeNode<K,V> find(int h, Object k, Class<?> kc) {
			TreeNode<K,V> p = this;
			do {
				int ph, dir;
				K pk;
				TreeNode<K,V> pl = p.left, pr = p.right, q;
				if ((ph = p.hash) > h)
				                    p = pl; else if (ph < h)
				                    p = pr; else if ((pk = p.key) == k || (k != null && k.equals(pk)))
				                    return p; else if (pl == null)
				                    p = pr; else if (pr == null)
				                    p = pl; else if ((kc != null ||
				                          (kc = comparableClassFor(k)) != null) &&
				                         (dir = compareComparables(kc, k, pk)) != 0)
				                    p = (dir < 0) ? pl : pr; else if ((q = pr.find(h, k, kc)) != null)
				                    return q; else
				                    p = pl;
			}
			while (p != null);
			return null;
		}
		/**
         * Calls find for root node.
         */
		final TreeNode<K,V> getTreeNode(int h, Object k) {
			return ((parent != null) ? root() : this).find(h, k, null);
		}
		/**
         * Tie-breaking utility for ordering insertions when equal
         * hashCodes and non-comparable. We don't require a total
         * order, just a consistent insertion rule to maintain
         * equivalence across rebalancings. Tie-breaking further than
         * necessary simplifies testing a bit.
         */
		static int tieBreakOrder(Object a, Object b) {
			int d;
			if (a == null || b == null ||
			                (d = a.getClass().getName().
			                 compareTo(b.getClass().getName())) == 0)
			                d = (System.identityHashCode(a) <= System.identityHashCode(b) ?
			                     -1 : 1);
			return d;
		}
		/**
         * Forms tree of the nodes linked from this node.
         * @return root of tree
         */
		final void treeify(Node<K,V>[] tab) {
			TreeNode<K,V> root = null;
			for (TreeNode<K,V> x = this, next; x != null; x = next) {
				next = (TreeNode<K,V>)x.next;
				x.left = x.right = null;
				if (root == null) {
					x.parent = null;
					x.red = false;
					root = x;
				} else {
					K k = x.key;
					int h = x.hash;
					Class<?> kc = null;
					for (TreeNode<K,V> p = root;;) {
						int dir, ph;
						K pk = p.key;
						if ((ph = p.hash) > h)
						                            dir = -1; else if (ph < h)
						                            dir = 1; else if ((kc == null &&
						                                  (kc = comparableClassFor(k)) == null) ||
						                                 (dir = compareComparables(kc, k, pk)) == 0)
						                            dir = tieBreakOrder(k, pk);
						TreeNode<K,V> xp = p;
						if ((p = (dir <= 0) ? p.left : p.right) == null) {
							x.parent = xp;
							if (dir <= 0)
							                                xp.left = x; else
							                                xp.right = x;
							root = balanceInsertion(root, x);
							break;
						}
					}
				}
			}
			moveRootToFront(tab, root);
		}
		/**
         * Returns a list of non-TreeNodes replacing those linked from
         * this node.
         */
		final Node<K,V> untreeify(HashMap<K,V> map) {
			Node<K,V> hd = null, tl = null;
			for (Node<K,V> q = this; q != null; q = q.next) {
				Node<K,V> p = map.replacementNode(q, null);
				if (tl == null)
				                    hd = p; else
				                    tl.next = p;
				tl = p;
			}
			return hd;
		}
		/**
         * Tree version of putVal.
         */
		final TreeNode<K,V> putTreeVal(HashMap<K,V> map, Node<K,V>[] tab,
		                                       int h, K k, V v) {
			Class<?> kc = null;
			Boolean searched = false;
			TreeNode<K,V> root = (parent != null) ? root() : this;
			for (TreeNode<K,V> p = root;;) {
				int dir, ph;
				K pk;
				if ((ph = p.hash) > h)
				                    dir = -1; else if (ph < h)
				                    dir = 1; else if ((pk = p.key) == k || (k != null && k.equals(pk)))
				                    return p; else if ((kc == null &&
				                          (kc = comparableClassFor(k)) == null) ||
				                         (dir = compareComparables(kc, k, pk)) == 0) {
					if (!searched) {
						TreeNode<K,V> q, ch;
						searched = true;
						if (((ch = p.left) != null &&
						                             (q = ch.find(h, k, kc)) != null) ||
						                            ((ch = p.right) != null &&
						                             (q = ch.find(h, k, kc)) != null))
						                            return q;
					}
					dir = tieBreakOrder(k, pk);
				}
				TreeNode<K,V> xp = p;
				if ((p = (dir <= 0) ? p.left : p.right) == null) {
					Node<K,V> xpn = xp.next;
					TreeNode<K,V> x = map.newTreeNode(h, k, v, xpn);
					if (dir <= 0)
					                        xp.left = x; else
					                        xp.right = x;
					xp.next = x;
					x.parent = x.prev = xp;
					if (xpn != null)
					                        ((TreeNode<K,V>)xpn).prev = x;
					moveRootToFront(tab, balanceInsertion(root, x));
					return null;
				}
			}
		}
		/**
         * Removes the given node, that must be present before this call.
         * This is messier than typical red-black deletion code because we
         * cannot swap the contents of an interior node with a leaf
         * successor that is pinned by "next" pointers that are accessible
         * independently during traversal. So instead we swap the tree
         * linkages. If the current tree appears to have too few nodes,
         * the bin is converted back to a plain bin. (The test triggers
         * somewhere between 2 and 6 nodes, depending on tree structure).
         */
		final void removeTreeNode(HashMap<K,V> map, Node<K,V>[] tab,
		                                  Boolean movable) {
			int n;
			if (tab == null || (n = tab.length) == 0)
			                return;
			int index = (n - 1) & hash;
			TreeNode<K,V> first = (TreeNode<K,V>)tab[index], root = first, rl;
			TreeNode<K,V> succ = (TreeNode<K,V>)next, pred = prev;
			if (pred == null)
			                tab[index] = first = succ; else
			                pred.next = succ;
			if (succ != null)
			                succ.prev = pred;
			if (first == null)
			                return;
			if (root.parent != null)
			                root = root.root();
			if (root == null || root.right == null ||
			                (rl = root.left) == null || rl.left == null) {
				tab[index] = first.untreeify(map);
				// too small
				return;
			}
			TreeNode<K,V> p = this, pl = left, pr = right, replacement;
			if (pl != null && pr != null) {
				TreeNode<K,V> s = pr, sl;
				while ((sl = s.left) != null) // find successor
				s = sl;
				Boolean c = s.red;
				s.red = p.red;
				p.red = c;
				// swap colors
				TreeNode<K,V> sr = s.right;
				TreeNode<K,V> pp = p.parent;
				if (s == pr) {
					// p was s's direct parent
					p.parent = s;
					s.right = p;
				} else {
					TreeNode<K,V> sp = s.parent;
					if ((p.parent = sp) != null) {
						if (s == sp.left)
						                            sp.left = p; else
						                            sp.right = p;
					}
					if ((s.right = pr) != null)
					                        pr.parent = s;
				}
				p.left = null;
				if ((p.right = sr) != null)
				                    sr.parent = p;
				if ((s.left = pl) != null)
				                    pl.parent = s;
				if ((s.parent = pp) == null)
				                    root = s; else if (p == pp.left)
				                    pp.left = s; else
				                    pp.right = s;
				if (sr != null)
				                    replacement = sr; else
				                    replacement = p;
			} else if (pl != null)
			                replacement = pl; else if (pr != null)
			                replacement = pr; else
			                replacement = p;
			if (replacement != p) {
				TreeNode<K,V> pp = replacement.parent = p.parent;
				if (pp == null)
				                    root = replacement; else if (p == pp.left)
				                    pp.left = replacement; else
				                    pp.right = replacement;
				p.left = p.right = p.parent = null;
			}
			TreeNode<K,V> r = p.red ? root : balanceDeletion(root, replacement);
			if (replacement == p) {
				// detach
				TreeNode<K,V> pp = p.parent;
				p.parent = null;
				if (pp != null) {
					if (p == pp.left)
					                        pp.left = null; else if (p == pp.right)
					                        pp.right = null;
				}
			}
			if (movable)
			                moveRootToFront(tab, r);
		}
		final void split(HashMap<K,V> map, Node<K,V>[] tab, int index, int bit) {
			TreeNode<K,V> b = this;
			// Relink into lo and hi lists, preserving order
			TreeNode<K,V> loHead = null, loTail = null;
			TreeNode<K,V> hiHead = null, hiTail = null;
			int lc = 0, hc = 0;
			for (TreeNode<K,V> e = b, next; e != null; e = next) {
				next = (TreeNode<K,V>)e.next;
				e.next = null;
				if ((e.hash & bit) == 0) {
					if ((e.prev = loTail) == null)
					                        loHead = e; else
					                        loTail.next = e;
					loTail = e;
					++lc;
				} else {
					if ((e.prev = hiTail) == null)
					                        hiHead = e; else
					                        hiTail.next = e;
					hiTail = e;
					++hc;
				}
			}
			if (loHead != null) {
				if (lc <= UNTREEIFY_THRESHOLD)
				                    tab[index] = loHead.untreeify(map); else {
					tab[index] = loHead;
					if (hiHead != null) // (else is already treeified)
					loHead.treeify(tab);
				}
			}
			if (hiHead != null) {
				if (hc <= UNTREEIFY_THRESHOLD)
				                    tab[index + bit] = hiHead.untreeify(map); else {
					tab[index + bit] = hiHead;
					if (loHead != null)
					                        hiHead.treeify(tab);
				}
			}
		}
		/* ------------------------------------------------------------ */
		// Red-black tree methods, all adapted from CLR
		static <K,V> TreeNode<K,V> rotateLeft(TreeNode<K,V> root,
		                                              TreeNode<K,V> p) {
			TreeNode<K,V> r, pp, rl;
			if (p != null && (r = p.right) != null) {
				if ((rl = p.right = r.left) != null)
				                    rl.parent = p;
				if ((pp = r.parent = p.parent) == null)
				                    (root = r).red = false; else if (pp.left == p)
				                    pp.left = r; else
				                    pp.right = r;
				r.left = p;
				p.parent = r;
			}
			return root;
		}
		static <K,V> TreeNode<K,V> rotateRight(TreeNode<K,V> root,
		                                               TreeNode<K,V> p) {
			TreeNode<K,V> l, pp, lr;
			if (p != null && (l = p.left) != null) {
				if ((lr = p.left = l.right) != null)
				                    lr.parent = p;
				if ((pp = l.parent = p.parent) == null)
				                    (root = l).red = false; else if (pp.right == p)
				                    pp.right = l; else
				                    pp.left = l;
				l.right = p;
				p.parent = l;
			}
			return root;
		}
		static <K,V> TreeNode<K,V> balanceInsertion(TreeNode<K,V> root,
		                                                    TreeNode<K,V> x) {
			x.red = true;
			for (TreeNode<K,V> xp, xpp, xppl, xppr;;) {
				if ((xp = x.parent) == null) {
					x.red = false;
					return x;
				} else if (!xp.red || (xpp = xp.parent) == null)
				                    return root;
				if (xp == (xppl = xpp.left)) {
					if ((xppr = xpp.right) != null && xppr.red) {
						xppr.red = false;
						xp.red = false;
						xpp.red = true;
						x = xpp;
					} else {
						if (x == xp.right) {
							root = rotateLeft(root, x = xp);
							xpp = (xp = x.parent) == null ? null : xp.parent;
						}
						if (xp != null) {
							xp.red = false;
							if (xpp != null) {
								xpp.red = true;
								root = rotateRight(root, xpp);
							}
						}
					}
				} else {
					if (xppl != null && xppl.red) {
						xppl.red = false;
						xp.red = false;
						xpp.red = true;
						x = xpp;
					} else {
						if (x == xp.left) {
							root = rotateRight(root, x = xp);
							xpp = (xp = x.parent) == null ? null : xp.parent;
						}
						if (xp != null) {
							xp.red = false;
							if (xpp != null) {
								xpp.red = true;
								root = rotateLeft(root, xpp);
							}
						}
					}
				}
			}
		}
		static <K,V> TreeNode<K,V> balanceDeletion(TreeNode<K,V> root,
		                                                   TreeNode<K,V> x) {
			for (TreeNode<K,V> xp, xpl, xpr;;)  {
				if (x == null || x == root)
				                    return root; else if ((xp = x.parent) == null) {
					x.red = false;
					return x;
				} else if (x.red) {
					x.red = false;
					return root;
				} else if ((xpl = xp.left) == x) {
					if ((xpr = xp.right) != null && xpr.red) {
						xpr.red = false;
						xp.red = true;
						root = rotateLeft(root, xp);
						xpr = (xp = x.parent) == null ? null : xp.right;
					}
					if (xpr == null)
					                        x = xp; else {
						TreeNode<K,V> sl = xpr.left, sr = xpr.right;
						if ((sr == null || !sr.red) &&
						                            (sl == null || !sl.red)) {
							xpr.red = true;
							x = xp;
						} else {
							if (sr == null || !sr.red) {
								if (sl != null)
								                                    sl.red = false;
								xpr.red = true;
								root = rotateRight(root, xpr);
								xpr = (xp = x.parent) == null ?
								                                    null : xp.right;
							}
							if (xpr != null) {
								xpr.red = (xp == null) ? false : xp.red;
								if ((sr = xpr.right) != null)
								                                    sr.red = false;
							}
							if (xp != null) {
								xp.red = false;
								root = rotateLeft(root, xp);
							}
							x = root;
						}
					}
				} else {
					// symmetric
					if (xpl != null && xpl.red) {
						xpl.red = false;
						xp.red = true;
						root = rotateRight(root, xp);
						xpl = (xp = x.parent) == null ? null : xp.left;
					}
					if (xpl == null)
					                        x = xp; else {
						TreeNode<K,V> sl = xpl.left, sr = xpl.right;
						if ((sl == null || !sl.red) &&
						                            (sr == null || !sr.red)) {
							xpl.red = true;
							x = xp;
						} else {
							if (sl == null || !sl.red) {
								if (sr != null)
								                                    sr.red = false;
								xpl.red = true;
								root = rotateLeft(root, xpl);
								xpl = (xp = x.parent) == null ?
								                                    null : xp.left;
							}
							if (xpl != null) {
								xpl.red = (xp == null) ? false : xp.red;
								if ((sl = xpl.left) != null)
								                                    sl.red = false;
							}
							if (xp != null) {
								xp.red = false;
								root = rotateRight(root, xp);
							}
							x = root;
						}
					}
				}
			}
		}
		/**
         * Recursive invariant check
         */
		static <K,V> Boolean checkInvariants(TreeNode<K,V> t) {
			TreeNode<K,V> tp = t.parent, tl = t.left, tr = t.right,
			                tb = t.prev, tn = (TreeNode<K,V>)t.next;
			if (tb != null && tb.next != t)
			                return false;
			if (tn != null && tn.prev != t)
			                return false;
			if (tp != null && t != tp.left && t != tp.right)
			                return false;
			if (tl != null && (tl.parent != t || tl.hash > t.hash))
			                return false;
			if (tr != null && (tr.parent != t || tr.hash < t.hash))
			                return false;
			if (t.red && tl != null && tl.red && tr != null && tr.red)
			                return false;
			if (tl != null && !checkInvariants(tl))
			                return false;
			if (tr != null && !checkInvariants(tr))
			                return false;
			return true;
		}
	}
}

Hashtable

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;
/*
和HashMap一样,Hashtable 也是一个散列表,它存储的内容是键值对(key-value)映射。
Hashtable 继承于Dictionary,实现了Map、Cloneable、java.io.Serializable接口。
Hashtable 的函数都是同步的,这意味着它是线程安全的。它的key、value都不可以为null。
此外,Hashtable中的映射不是有序的。
*/
public class Hashtable<K,V>
    extends Dictionary<K,V>
    implements Map<K,V>, Cloneable, java.io.Serializable {
	/**
     * hashtable中的数据
     */
	private transient Entry<?,?>[] table;
	/**
     * 表中的元素的实际数量
     */
	private transient int count;
	/**
     * 阈值,判断是否需要调整容量
     */
	private int threshold;
	/**
     * 加载因子,一般0.75
	 */
	private float loadFactor;
	/**
     *对于表的操作次数,可以判断
	 *是否有并发线程对其进行改动,并返回错误
     */
	private transient int modCount = 0;
	/**
	*版本号
	*/
	private static final long serialVersionUID = 1421746759512286392L;
	/**
     * 构造器:有初始容量和加载因子
     */
	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);
		//阈值大小
	}
	/**
     * 构造器:加载因子为0.75默认,有初始容量
     */
	public Hashtable(int initialCapacity) {
		this(initialCapacity, 0.75f);
	}
	/**
     * 构造器:加载因子0.75,初始容量11
     */
	public Hashtable() {
		this(11, 0.75f);
	}
	/**
     * 构造器:有Map映射,构造器初始容量大于映射的两倍
     */
	public Hashtable(Map<? extends K, ? extends V> t) {
		this(Math.max(2*t.size(), 11), 0.75f);
		putAll(t);
	}
	/**
     * 最大容量为int最大值-8
     */
	private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
	/**
     * 动态改变容量大小
     */
	@SuppressWarnings("unchecked")
	    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)//判断老的容量与最大值的关系
			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;
				//赋值
			}
		}
	}
	/**
     * 删除某个词条
     */
	public synchronized V remove(Object key) {
		Entry<?,?> tab[] = table;
		int hash = key.hashCode();
		int index = (hash & 0x7FFFFFFF) % tab.length;
		@SuppressWarnings("unchecked")
		        Entry<K,V> e = (Entry<K,V>)tab[index];
		//通过key计算hash值并进一步确定位置
		for (Entry<K,V> prev = null ; e != null ; prev = e, e = e.next) {
			if ((e.hash == hash) && e.key.equals(key)) {
				modCount++;
				if (prev != null) {
					prev.next = e.next;
				} else {
					tab[index] = e.next;
					//将key对应的词条的上和下链接起来
				}
				count--;
				//数量减1
				V oldValue = e.value;
				e.value = null;
				//对应处的数值改为Null
				return oldValue;
			}
		}
		return null;
	}
	/**
     * 复制某一Map的所有词条至表中
     */
	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());
	}
	// Views
	/**
     * 所有的key,entry,values都要加一个锁,保证不发生并发改变的问题
     */
	private transient volatile Set<K> keySet;
	private transient volatile Set<Map.Entry<K,V>> entrySet;
	private transient volatile Collection<V> values;
	/**
     * 
     */
	public Set<K> keySet() {
		if (keySet == null)
		            keySet = Collections.synchronizedSet(new KeySet(), this);
		return 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();
		}
	}
	/**
     * 
     */
	public Set<Map.Entry<K,V>> entrySet() {
		if (entrySet==null)
		            entrySet = Collections.synchronizedSet(new EntrySet(), this);
		return entrySet;
	}
	private class EntrySet extends AbstractSet<Map.Entry<K,V>> {
		public Iterator<Map.Entry<K,V>> iterator() {
			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)
			                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();
		}
	}
	/**
     * 
     */
	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() {
			return getIterator(VALUES);
		}
		public int size() {
			return count;
		}
		public Boolean contains(Object o) {
			return containsValue(o);
		}
		public void clear() {
			Hashtable.this.clear();
		}
	}
	/**
     * 判等
     */
	public synchronized Boolean equals(Object o) {
		if (o == this)//正好相等
		return true;
		if (!(o instanceof Map))//类型不一致
		return false;
		Map<?,?> t = (Map<?,?>) o;
		if (t.size() != size())
		            return false;
		try {
			//判断不相等
			Iterator<Map.Entry<K,V>> i = entrySet().iterator();
			while (i.hasNext()) {
				Map.Entry<K,V> e = i.next();
				K key = e.getKey();
				V value = e.getValue();
				if (value == null) {
					if (!(t.get(key)==null && t.containsKey(key)))//不存在相同key值
					return false;
				} else {
					if (!value.equals(t.get(key)))//key对应的位置存在但值不相等
					return false;
				}
			}
		}
		catch (ClassCastException unused)   {
			return false;
		}
		catch (NullPointerException unused) {
			return false;
		}
		return true;
	}
	/**
     * 返回hashcode值
     */
	public synchronized int hashCode() {
		int h = 0;
		if (count == 0 || loadFactor < 0)
		            return h;
		// 空
		loadFactor = -loadFactor;
		// 加载因子改为负,作标记,不能被其他进程更改
		Entry<?,?>[] tab = table;
		for (Entry<?,?> entry : tab) {
			while (entry != null) {
				h += entry.hashCode();
				//hashcode的计算方式:相加该位置所有链接的hash值
				entry = entry.next;
			}
		}
		loadFactor = -loadFactor;
		return h;
	}
	/*
	*按照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;
	}
	/**
     * 通过流保存文件
     */
	private void writeObject(java.io.ObjectOutputStream s)
	            throws IOException {
		Entry<Object, Object> entryStack = null;
		synchronized (this) {
			s.defaultWriteObject();
			s.writeint(table.length);
			s.writeint(count);
			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;
				}
			}
		}
		while (entryStack != null) {
			s.writeObject(entryStack.key);
			s.writeObject(entryStack.value);
			entryStack = entryStack.next;
		}
	}
	/**
     * 词条
     */
	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;
		}
		@SuppressWarnings("unchecked")
		        protected Object clone() {
			return new Entry<>(hash, key, value,
			                                  (next==null ? null : (Entry<K,V>) next.clone()));
		}
		// Map.Entry Ops
		public K getKey() {
			return key;
		}
		public V getValue() {
			return value;
		}
		public V setValue(V value) {
			if (value == null)
			                throw new NullPointerException();
			V oldValue = this.value;
			this.value = value;
			return oldValue;
		}
		public Boolean equals(Object o) {
			if (!(o instanceof Map.Entry))
			                return false;
			Map.Entry<?,?> e = (Map.Entry<?,?>)o;
			return (key==null ? e.getKey()==null : key.equals(e.getKey())) &&
			               (value==null ? e.getValue()==null : value.equals(e.getValue()));
		}
		public int hashCode() {
			return hash ^ Objects.hashCode(value);
		}
		public String toString() {
			return key.toString()+"="+value.toString();
		}
	}
}
posted @ 2020-08-18 22:21  流沙uiui  阅读(119)  评论(0编辑  收藏  举报