> 学习源码之前,最好在脑海中明确 HashMap 的存储结构,不然后面阅读源码,遇到容量、数量等参数可能会有些许困惑。
相信你已经有所耳闻,HashMap 内部包含了一个 Node 类型的数组 table。Node 存储着键值对。
Node 类源码如下:
```java
static class Node<K, V> implements Map.Entry<K, V> {
final int hash;
final K key;
V value;
Node<K, V> next;
Node(int hash, K key, V value, Node<K, V> next) {
this.hash = hash;
this.key = key;
this.value = value;
this.next = next;
}
public final K getKey() {
return key;
}
public final V getValue() {
return value;
}
public final String toString() {
return key + "=" + value;
}
public final int hashCode() {
return Objects.hashCode(key) ^ Objects.hashCode(value);
}
public final V setValue(V newValue) {
V oldValue = value;
value = newValue;
return oldValue;
}
public final boolean equals(Object o) {
if (o == this) {
return true;
}
if (o instanceof Map.Entry) {
Map.Entry<?, ?> e = (Map.Entry<?, ?>) o;
if (Objects.equals(key, e.getKey()) &&
Objects.equals(value, e.getValue())) {
return true;
}
}
return false;
}
}
```
它包含了四个字段,从 next 字段我们可以看出 Node 是一个链表。即数组中的每个位置被当成一个桶,一个桶存放一个链表。HashMap 使用链地址法来解决哈希冲突,即同一个链表中存放**哈希值和散列桶取模运算结果相同**的 Node。HashMap 存储结构如下图所示:
![](https://img.kancloud.cn/1e/fc/1efc7f76d96fd82e7f070095165cb838_1442x996.png)