源码探究Java_HashMap
1. HashMap 定义,抽取HashMap类中主要变量,如下
public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable { /** map中键值对的数量 */ transient int size; /** 阀值 (阀值=加载因子*容量),达到后则扩容 */ int threshold; /** 加载因子,默认0.75*/ final float loadFactor; /** 计算hash值的种子*/ transient int hashSeed = 0; /** 数组 */ transient Entry<K,V>[] table = (Entry<K,V>[]) EMPTY_TABLE; /** 链表节点定义 */ static class Entry<K,V> implements Map.Entry<K,V> { /** 键名 */ final K key; /** 键值 */ V value; /** 后继节点 */ Entry<K,V> next; /** 当前key的hash值 */ int hash; } }
2. hash值如何计算
final int hash(Object k) { int h = hashSeed;
/** 字符串hash计算 */ if (0 != h && k instanceof String) { return sun.misc.Hashing.stringHash32((String) k); } h ^= k.hashCode(); /**此函数确保在每个位位置仅相差常数倍的hashCodes具有有限的冲突数(默认加载因子大约为8)*/ h ^= (h >>> 20) ^ (h >>> 12); return h ^ (h >>> 7) ^ (h >>> 4); }
3. 在上一步中查看字符串怎么计算hash值的时候发现HashMap内部的一个恶汉式的单例实现
private static class Holder { static final JavaLangAccess LANG_ACCESS = SharedSecrets.getJavaLangAccess(); private Holder() { } static { if(null == LANG_ACCESS) { throw new Error("Shared secrets not initialized"); } } }