Java HashMap 解析

public class HashMap<K, V> extends AbstractMap<K, V> implements Map<K, V>, Cloneable, Serializable {
	static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; //默认的初始容量-必须是2的幂。
	static final int MAXIMUM_CAPACITY = 1 << 30;	    //最大容量,如果较高的值是由任何带有参数的构造函数隐式指定的。必须是2的幂<= 1<<30。
	static final float DEFAULT_LOAD_FACTOR = 0.75f;	    //在构造函数中未指定时使用的负载因子。
	static final int TREEIFY_THRESHOLD = 8;				//树的临界值
	static final int UNTREEIFY_THRESHOLD = 6;			//在调整大小操作期间取消(分割)存储库的存储计数阈值。应小于TREEIFY_THRESHOLD,并最多6个网格与收缩检测下去除。
	static final int MIN_TREEIFY_CAPACITY = 64;     	//最小的表容量,可为容器进行树状排列。
	transient Node<K, V>[] table;   			//表,在第一次使用时初始化,并根据需要调整大小。分配时,长度总是2的幂。
	transient Set<Map.Entry<K, V>> entrySet;			//保存缓存
	transient int size;					//这个映射中包含的键值映射的数量。
	transient int modCount;				//修改的次数
	int threshold;						//调整大小的下一个大小值(容量*负载因子)。
	final float loadFactor;				//哈希表的负载因子。

	//在第一次请求该视图时,每个字段都被初始化为包含适当视图的实例。视图是无状态的,因此没有理由创建多个视图。
	transient volatile Set<K>  keySet;		(AbstractMap)	  
	transient volatile Collection<V> values; 	(AbstractMap)	  

	//基本哈希bin节点,用于大多数条目。(参见下面的TreeNode子类,以及LinkedHashMap中的条目子类)
	static class Node<K, V> implements Map.Entry<K, V> {
		final int hash; //哈希值
		final K key;	//键
		V value;	//值
		Node<K, V> next;//下一个值
	}

	static final int hash(Object key){ //key的hashcode ^ hashCode >>> 16
		int h;
		return (key==null) ? 0 :(h = key.hashCode()) ^ (h >>> 16);
	}
	static final int tableSizeFor(int cap){ //该方法保证了容量的长度是2的n次幂
		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;
	}

 

	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) {    //如果容量大于0(这时候table不为null了, oldCap为16的n次幂)
            if (oldCap >= MAXIMUM_CAPACITY) {  //如果容量大于最大值(1 << 30)
                threshold = Integer.MAX_VALUE;   //取最大值
                return oldTab;
            } else if ((newCap = oldCap << 1) < MAXIMUM_CAPACITY && oldCap >= DEFAULT_INITIAL_CAPACITY) {  //扩容(原容量*2)  并且大于等于默认容量16
                newThr = oldThr << 1; // 扩容阈值(原阈值*2)  12的n次幂
            }
        } else if (oldThr > 0) {    // 初始容量设为阈值
            newCap = oldThr;
        } else {                // 零初始阈值表示使用默认值(第一次 put() 的时候 默认容量为16  扩容阈值为12)
            newCap = DEFAULT_INITIAL_CAPACITY;  // 16
            newThr = (int) (DEFAULT_LOAD_FACTOR * DEFAULT_INITIAL_CAPACITY);   // 16 * 0.75f = 12
        }
        if (newThr == 0) {    //如果阈值为0 设置阈值(新的容量*扩展因子0.75f)
            float ft = (float) newCap * loadFactor;
            newThr = (newCap < MAXIMUM_CAPACITY && ft < (float) MAXIMUM_CAPACITY ? (int) ft : Integer.MAX_VALUE);
        }
        threshold = newThr;  //扩容阈值 = 新的扩容阈值

        Node<K, V>[] newTab = (Node<K, V>[]) new Node[newCap];  //实例化新的表
        table = newTab;        //赋值给当前table
        if (oldTab != null) {    //第一次put除外 就不为空
            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 {    // preserve order
                        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) {
                                if (loTail == null)
                                    loHead = e;
                                else
                                    loTail.next = e;
                                loTail = 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;
    }
}

猜你喜欢

转载自blog.csdn.net/baidu_36327010/article/details/88192831