HashMap实现了Map接口,并继承 AbstractMap 抽象类,其中 Map 接口定义了键值映射规则。AbstractMap 抽象类提供了 Map 接口的骨干实现,以最大限度地减少实现Map接口所需的工作。
public class HashMap<K,V>
extends AbstractMap<K,V>
implements Map<K,V>, Cloneable, Serializable{
...
}
初始容量 和 负载因子,这两个参数是影响HashMap性能的重要参数。其中,容量表示哈希表中桶的数量 (table 数组的大小),初始容量是创建哈希表时桶的数量;负载因子是哈希表在其容量自动增加之前可以达到多满的一种尺度,它衡量的是一个散列表的空间的使用程度,负载因子越大表示散列表的装填程度越高,反之愈小。
哈希的相关概念
Hash 就是把任意长度的输入(又叫做预映射, pre-image),通过哈希算法,变换成固定长度的输出(通常是整型),该输出就是哈希值。这种转换是一种 压缩映射 ,也就是说,散列值的空间通常远小于输入的空间。不同的输入可能会散列成相同的输出,从而不可能从散列值来唯一的确定输入值。简单的说,就是一种将任意长度的消息压缩到某一固定长度的息摘要函数。

1 /**
2 * Constructs an empty HashMap with the default initial capacity
3 * (16) and the default load factor (0.75).
4 */
5 public HashMap() {
6
7 //负载因子:用于衡量的是一个散列表的空间的使用程度
8 this.loadFactor = DEFAULT_LOAD_FACTOR;
9
10 //HashMap进行扩容的阈值,它的值等于 HashMap 的容量乘以负载因子
11 threshold = (int)(DEFAULT_INITIAL_CAPACITY * DEFAULT_LOAD_FACTOR);
12
13 // HashMap的底层实现仍是数组,只是数组的每一项都是一条链
14 table = new Entry[DEFAULT_INITIAL_CAPACITY];
15
16 init();
17 }
18
19
20
21 static class Entry<K,V> implements Map.Entry<K,V> {
22
23 final K key; // 键值对的键
24 V value; // 键值对的值
25 Entry<K,V> next; // 下一个节点
26 final int hash; // hash(key.hashCode())方法的返回值
27
28 /**
29 * Creates new entry.
30 */
31 Entry(int h, K k, V v, Entry<K,V> n) { // Entry 的构造函数
32 value = v;
33 next = n;
34 key = k;
35 hash = h;
36 }
37
38 ......
39
40 }
其中,Entry为HashMap的内部类,实现了 Map.Entry 接口,其包含了键key、值value、下一个节点next,以及hash值四个属性。事实上,Entry 是构成哈希表的基石,是哈希表所存储的元素的具体形式。
在 HashMap 中,键值对的存储是通过 put(key,vlaue) 方法来实现的,其源码如下:

1 public V put(K key, V value) {
2
3 //当key为null时,调用putForNullKey方法,并将该键值对保存到table的第一个位置
4 if (key == null)
5 return putForNullKey(value);
6
7 //根据key的hashCode计算hash值
8 int hash = hash(key.hashCode()); // ------- (1)
9
10 //计算该键值对在数组中的存储位置(哪个桶)
11 int i = indexFor(hash, table.length); // ------- (2)
12
13 //在table的第i个桶上进行迭代,寻找 key 保存的位置
14 for (Entry<K,V> e = table[i]; e != null; e = e.next) { // ------- (3)
15 Object k;
16 //判断该条链上是否存在hash值相同且key值相等的映射,若存在,则直接覆盖 value,并返回旧value
17 if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
18 V oldValue = e.value;
19 e.value = value;
20 e.recordAccess(this);
21 return oldValue; // 返回旧值
22 }
23 }
24
25 modCount++; //修改次数增加1,快速失败机制
26
27 //原HashMap中无该映射,将该添加至该链的链头
28 addEntry(hash, key, value, i);
29 return null;
30 }
