static class Entry<K,V> implements Map.Entry<K,V> {
final K key;
V value;
Entry<K,V> next;
int hash;
// 创建一个新的节点, 将传入的接点挂在到新的节点下
Entry(int h, K k, V v, Entry<K,V> n) {
value = v;
next = n;
key = k;
hash = h;
}
}
3. newHashMap()
// 默认的初始容量-必须是2的幂。
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
// 默认负载因子
static final float DEFAULT_LOAD_FACTOR = 0.75f;
// 一般为 capacity*loadFactory,如果数组容量大于threshold就会扩容
int threshold;
public HashMap() {
this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR);
}
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;
threshold = initialCapacity;
// 空的, linkedHashMap才有
init();
}
4. put(K key, V value)
// 放置元素的数组, 大小为2的n次幂
transient Entry<K,V>[] table = (Entry<K,V>[]) EMPTY_TABLE;
public V put(K key, V value) {
// 如果数组为空, 那么进行膨胀
if (table == EMPTY_TABLE) {
// 此时 threshold = initialCapacity = 1 << 4 = 16
inflateTable(threshold);
}
// 如果key为null, 走一段特殊逻辑, 将它挂到数组的第一个下标位置
if (key == null)
return putForNullKey(value);
// 获取hash值, 这个hash值和hash因子有关
int hash = hash(key);
// 获取数组下标位置
int i = indexFor(hash, table.length);
// 遍历数组查看里面有没有相同的key, 如果有则覆盖,并返回老的value
for (Entry<K,V> e = table[i]; e != null; e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
// 快速失败机制
modCount++;
// 添加入链表
addEntry(hash, key, value, i);
return null;
}
// 返回小于等于i的 2的n次幂
public static int highestOneBit(int i) {
// HD, Figure 3-1
i |= (i >> 1);
i |= (i >> 2);
i |= (i >> 4);
i |= (i >> 8);
i |= (i >> 16);
return i - (i >>> 1);
}
分析:
int类型有4个字节, 每个字节8位, 共计32位以下分析仅仅代表i为正数的情况下
假设i=1070,
0000 0000 0000 0000 0000 0100 0010 1110// i
0000 0000 0000 0000 0000 0010 0001 0111// i >> 1
0000 0000 0000 0000 0000 0110 0011 1111// i |= (i >> 1)
0000 0000 0000 0000 0000 0001 1000 1111// i >> 2
0000 0000 0000 0000 0000 0111 1011 1111// i |= (i >> 2)
0000 0000 0000 0000 0000 0000 0111 1011// i >> 4
0000 0000 0000 0000 0000 0111 1111 1111// i |= (i >> 4)
0000 0000 0000 0000 0000 0000 0000 0111// i >> 8
0000 0000 0000 0000 0000 0111 1111 1111// i |= (i >> 8)
0000 0000 0000 0000 0000 0000 0000 0000// i >> 16
0000 0000 0000 0000 0000 0111 1111 1111// i |= (i >> 16)
0000 0000 0000 0000 0000 0011 1111 1111// i >>> 1
0000 0000 0000 0000 0000 0100 0000 0000// i - (i >>> 1)