参数解析
//默认最小容量为4
private static final int MINIMUM_CAPACITY = 4;
//最大容量
private static final int MAXIMUM_CAPACITY = 1 << 30;
//默认是0.75即当加载超过0.75就进行扩容
static final float DEFAULT_LOAD_FACTOR = .75F;
//存放key和value的表
transient HashMapEntry<K, V>[] table;
//没有key的表
transient HashMapEntry<K, V> entryForNullKey;
//hashMap的数量
transient int size;
//key的集合,用set的原因key不可重复
private transient Set<K> keySet;
private transient Set<Entry<K, V>> entrySet;
//value可以重复
private transient Collection<V> values;
首先看HashMapEntry源码
static class HashMapEntry<K, V> implements Entry<K, V> {
final K key;//key值
V value;//value值
final int hash;//hash值
//指向下一个指针
HashMapEntry<K, V> next;
HashMapEntry(K key, V value, int hash, HashMapEntry<K, V> next) {
this.key = key;
this.value = value;
this.hash = hash;
this.next = next;
}
public final K getKey() {//获得key
return key;
}
public final V getValue() {//获得value值
return value;
}
public final V setValue(V value) {//设置value
V oldValue = this.value;
this.value = value;
return oldValue;
}
@Override public final boolean equals(Object o) {
if (!(o instanceof Entry)) {//若不是Entry直接返回false
return false;
}
Entry<?, ?> e = (Entry<?, ?>) o;
//key和value都要相等
return Objects.equal(e.getKey(), key)
&& Objects.equal(e.getValue(), value);
/**
* public static boolean equals(Object a, Object b) {
* return (a == null) ? (b == null) : a.equals(b);
* }
*/
}
@Override public final int hashCode() {
return (key == null ? 0 : key.hashCode()) ^
(value == null ? 0 : value.hashCode());
}
@Override public final String toString() {
return key + "=" + value;
}
}
构造函数源码分析
public HashMap(int capacity) {//capacity容量的意思
if (capacity < 0) {//如果容量小于0
throw new IllegalArgumentException("Capacity: " + capacity);
}
if (capacity == 0) {//等于0代表将创建一个空表
@SuppressWarnings("unchecked")
HashMapEntry<K, V>[] tab = (HashMapEntry<K, V>[]) EMPTY_TABLE;
table = tab;
threshold = -1; //threshold和容量有关
return;
}
//这里设置的目的就是要大于等于4小于等于2<<30
if (capacity < MINIMUM_CAPACITY) {
capacity = MINIMUM_CAPACITY;
} else if (capacity > MAXIMUM_CAPACITY) {
capacity = MAXIMUM_CAPACITY;
} else {
//以2倍进行扩容看下源码
capacity = Collections.roundUpToPowerOfTwo(capacity);
}
makeTable(capacity);
}
roundUpToPowerOfTwo源码分析
public static int roundUpToPowerOfTwo(int i) {
i--; //比如当前输入的i是9,二进制就是1001 减去1之后就是1000
//通俗点就是i等于9,2的3次方是8小于9所以返回的是2的4次方
i |= i >>> 1;
i |= i >>> 2;
i |= i >>> 4;
i |= i >>> 8;
i |= i >>> 16;
return i + 1;
}
makeTable源码解析
private HashMapEntry<K, V>[] makeTable(int newCapacity) {
//根据大小创建一个新的HashMapEntry表
@SuppressWarnings("unchecked") HashMapEntry<K, V>[] newTable
= (HashMapEntry<K, V>[]) new HashMapEntry[newCapacity];
table = newTable;
//如果threshold超过0.75就会扩容
threshold = (newCapacity >> 1) + (newCapacity >> 2); // 3/4 的能力
return newTable;
}
put源码解析
@Override public V put(K key, V value) {
if (key == null) {//如果key为空的话存放在putValueForNullKey这个表
return putValueForNullKey(value);
}
//这个会获取key的哈希值,然后在进行运算,即hash获得的是二次运算哈希值
int hash = Collections.secondaryHash(key);
//处于系统安全考虑,所以没有直接用table进行计算
HashMapEntry<K, V>[] tab = table;
//获得下标
int index = hash & (tab.length - 1);
//for循环进行遍历获得数据
for (HashMapEntry<K, V> e = tab[index]; e != null; e = e.next) {
//如果key和hash值都相等,则进行修改其中的值
if (e.hash == hash && key.equals(e.key)) {
preModify(e);
V oldValue = e.value;
e.value = value;
return oldValue;
}
}
modCount++;
if (size++ > threshold) {//如果大小大于0.75
//获得扩容后的表
tab = doubleCapacity();
//重新获得下标
index = hash & (tab.length - 1);
}
//添加源码解析
addNewEntry(key, value, hash, index);
return null;
}
doubleCapacity源码分析
private HashMapEntry<K, V>[] doubleCapacity() {
//获得旧表
HashMapEntry<K, V>[] oldTable = table;
int oldCapacity = oldTable.length;
//旧表的容量已经达到最大,则返回最大旧表
if (oldCapacity == MAXIMUM_CAPACITY) {
return oldTable;
}
//否则进行双倍扩容
int newCapacity = oldCapacity * 2;
HashMapEntry<K, V>[] newTable = makeTable(newCapacity);
if (size == 0) {
return newTable;
}
for (int j = 0; j < oldCapacity; j++) {
//遍历旧表中的数据
HashMapEntry<K, V> e = oldTable[j];
if (e == null) {//如果为空直接结束
continue;
}
//旧表的下标
int highBit = e.hash & oldCapacity;
HashMapEntry<K, V> broken = null;
//指定新表数据
newTable[j | highBit] = e;
for (HashMapEntry<K, V> n = e.next; n != null; e = n, n = n.next) {
//获得新表的下标
int nextHighBit = n.hash & oldCapacity;
if (nextHighBit != highBit) {
if (broken == null)
newTable[j | nextHighBit] = n;
else
broken.next = n;
broken = e;
highBit = nextHighBit;
}
}
if (broken != null)
broken.next = null;
}
return newTable;
}
addNewEntry源码解析
void addNewEntry(K key, V value, int hash, int index) {
//指定table的下一个next指向
table[index] = new HashMapEntry<K, V>(key, value, hash, table[index]);
}
get源码解析
public V get(Object key) {
if (key == null) {//key是否为空
HashMapEntry<K, V> e = entryForNullKey;
return e == null ? null : e.value;
}
//获得二次运算的哈希值
int hash = Collections.secondaryHash(key);
HashMapEntry<K, V>[] tab = table;
//hash & (tab.length - 1)获得下标
for (HashMapEntry<K, V> e = tab[hash & (tab.length - 1)];
e != null; e = e.next) {
//获取key
K eKey = e.key;
//如果想等,则直接返回值
if (eKey == key || (e.hash == hash && key.equals(eKey))) {
return e.value;
}
}
return null;
}
remove源码分析
@Override public V remove(Object key) {
if (key == null) {
return removeNullKey();
}
//获得二次运算哈希值
int hash = Collections.secondaryHash(key);
HashMapEntry<K, V>[] tab = table;
int index = hash & (tab.length - 1);//获得下标
for (HashMapEntry<K, V> e = tab[index], prev = null;
e != null; prev = e, e = e.next) {
if (e.hash == hash && key.equals(e.key)) {//如果相等移除e
if (prev == null) {//如果是头部
tab[index] = e.next;//移除头部
} else {
prev.next = e.next;//前一个指向下一个
}
modCount++;
size--;
postRemove(e);
return e.value;
}
}
return null;
}