一、类属性
//默认容量16
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4;
//最大容量2的30次方
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;
二、对象属性
//Node数组
transient Node<K, V>[] table;
//Entry集合
transient Set<Map.Entry<K, V>> entrySet;
//当前Map的长度
transient int size;
/**
* 已对HashMap进行结构修改的次数。
* 结构修改是指更改HashMap中的节点或以其他方式修改其内部结构(例如,节点的增加和修改)的修改。
* 此字段用于使HashMap的Collection-view上的迭代器快速失败。
* (请参见ConcurrentModificationException)
*/
transient int modCount;
/**
* 下一个要调整大小的大小值(capacity*loadFactor),扩容位置。
*/
int threshold;
/**
* 加载因子
*/
final float loadFactor;
三、构造方法中会用到的方法
/**
* @return 大于当前传入数字的最小2次幂的值,如果结果大于最大允许容量,则返回最大运行容量值
*/
static int tableSizeFor(int cap) {
int n = cap - 1;
n |= n >>> 1;
n |= n >>> 2;
n |= n >>> 4;
n |= n >>> 8;
n |= n >>> 16;
if (n < 0) {
return 1;
} else {
if (n >= MAXIMUM_CAPACITY) {
return MAXIMUM_CAPACITY;
} else {
return n + 1;
}
}
}
/**
* @param evict 最初构造此Map时为false,否则为true(中继到afterNodeInsertion方法)。
*/
final void putMapEntries(Map<? extends K, ? extends V> m, boolean evict) {
//获得参数Map的参数长度
int s = m.size();
if (s > 0) {
//如果当前Map没有初始化
if (table == null) {
//计算参数Map出去当前Map的加载因子
//作用在于如果参数Map大小+1设置为当前Map的threshold(扩容位置)是否会大于最大容量
float ft = ((float) s / loadFactor) + 1.0F;
//比较最大容量与ft,取小值;
int t = ((ft < (float) MAXIMUM_CAPACITY) ?
(int) ft : MAXIMUM_CAPACITY);
//如果t大于当前Map的threshold(扩容位置)
if (t > threshold) {
//重新计算当前Map的扩容位置
threshold = tableSizeFor(t);
}
} else if (s > threshold) {
//如果当前Map已经初始化,且参数Map的大小大于扩容位置
//进行扩容
resize();
}
//遍历参数Map的Node节点放入当前Map
for (Entry<? extends K, ? extends V> e : m.entrySet()) {
K key = e.getKey();
V value = e.getValue();
putVal(hash(key), key, value, false, evict);
}
}
}
四、构造方法
/**
* 用HashMap(int initialCapacity, float loadFactor)和HashMap(int initialCapacity)
* 方法创建HashMap对象会初始化扩容位置threshold,大小为tableSizeFor(initialCapacity)
* 但是在初始化后会进行修正
*/
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;
}
public HashMap(Map<? extends K, ? extends V> m) {
this.loadFactor = DEFAULT_LOAD_FACTOR;
putMapEntries(m, false);
}
五、其他一些方法
为下面的章节做铺垫
/**
* @return key为null返回0,key不为空返回key的后16位和前16位的异或运算结果
*/
static <K> int hash(K key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
Node<K, V> newNode(int hash, K key, V value, Node<K, V> next) {
return new Node<>(hash, key, value, next);
}
/*用于从TreeNodes转换为Node*/
Node<K, V> replacementNode(Node<K, V> p, Node<K, V> next) {
return new Node<>(p.hash, p.key, p.value, next);
}
TreeNode<K, V> newTreeNode(int hash, K key, V value, Node<K, V> next) {
return new TreeNode<>(hash, key, value, next);
}
/*用于从Node转换为TreeNode*/
TreeNode<K, V> replacementTreeNode(Node<K, V> p, Node<K, V> next) {
return new TreeNode<>(p.hash, p.key, p.value, next);
}