1. 数据结构
HashMap的数据结构是:数组+链表+红黑树。
2. 成员变量
# 默认的数组长度 16
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
# 最大的数组长度2的30次方
static final int MAXIMUM_CAPACITY = 1 << 30;
# 加载因子
static final float DEFAULT_LOAD_FACTOR = 0.75f;
# 链表长度达到8的时候转化为红黑树
static final int TREEIFY_THRESHOLD = 8;
# 红黑树节点数小于6的时候转成链表
static final int UNTREEIFY_THRESHOLD = 6;
# 转化为红黑树时数组的最小长度
static final int MIN_TREEIFY_CAPACITY = 64;
# node数组
transient Node<K,V>[] table;
# 数组容量=数组长度capacity*加载因子loadfactor,当节点数超过这个数时,数组扩容
# 如果数组还没有初始化,保存的是初始化数组的长度或者是0,详情见构造方法
int threshold;
3. 构造方法
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);
}
public HashMap(int initialCapacity) {
this(initialCapacity, DEFAULT_LOAD_FACTOR);
}
public HashMap() {
this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted
}
未指定数组初始容量initialCapacity时:所有参数都是使用默认的
当指定数组初始容量initialCapacity时:
1.首先校验了参数的合法性
2.调用tableSizeFor()方法求出比initialCapacity大的,并且离initialCapacity最近的2的n次方数,保存到threadhold变量上, 以供第一次put元素的时候初始化数组。