前面写了JDK1.7中的HashMap源码分析,本篇将对JDK1.8中的HashMap源码进行简单的分析。
一、HashMap底层数据结构
JDK7:数组+链表
JDK8: 数组+链表+红黑树
二、HashMap重要属性
/**
* 数组默认的初始化容量为16
*/
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
/**
* 数组最大容量
*/
static final int MAXIMUM_CAPACITY = 1 << 30;
/**
* 数组默认的加载因子。
*/
static final float DEFAULT_LOAD_FACTOR = 0.75f;
/**
* 数组元素上的链表的节点数大于这个值时会转成红黑树
*/
static final int TREEIFY_THRESHOLD = 8;
/**
* 当数组元素上的树长度小于等于UNTREEIFY_THRESHOLD(默认为6)时,会退化回链表
*/
static final int UNTREEIFY_THRESHOLD = 6;
/**
* 数组元素中结构转化为红黑树对应的数组的最小大小,如果当前容量小于它,就不会将链表转化为红黑树,而是用resize()代替
*/
static final int MIN_TREEIFY_CAPACITY = 64;
三、解析PUT方法
final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
boolean evict) {
//数组类型为Node
Node<K,V>[] tab; Node<K,V> p; int n, i;
// 步骤①:tab为空则创建
// table未初始化或者长度为0,进行初始化扩容
if ((tab = table) == null || (n = tab.length) == 0)
n = (tab = resize()).length;
//如果数组不为空,当前位置没有数据,则将传入的k v放在此处
if ((p = tab[i = (n - 1) & hash]) == null)
tab[i] = newNode(hash, key, value, null);
else {
Node<K,V> e; K k;
// 步骤③:节点key存在,直接覆盖value
// 如果传入的key计算后的数组下标下有数据并且与传入的key相同
if (p.hash == hash &&