Java 8 HashMap 详解
HashMap 实现了Map接口,继承于 AbstractMap。利用散列表来实现 Key-Value 元素的存取。散列表是用链表数组实现的,每个列表被称为桶 (bucket)。利用 key 的 hashcode 来确保元素的唯一性。HashMap 不保证元素的顺序恒定不变,在扩充的过程中,键值对元素位置会被再分配。
这里主要基于 JDK1.8 版本的 HashMap 源码进行分析。Map 相关的类图如下所示:
HashMap构造
HashMap 有两个参数影响其性能:初始容量和加载因子。容量是哈希表中桶的数量,初始容量是哈希表在创建时的容量。加载因子是哈希表在其容量自动增加之前可以达到多满的一种尺度。
HashMap 提供了三种构造函数。第一种通过直接设置初始容量和加载因子。
/**
* Constructs an empty HashMap with the specified initial
* capacity and load factor.
*
* @param initialCapacity the initial capacity
* @param loadFactor the load factor
* @throws IllegalArgumentException if the initial capacity is negative
* or the load factor is nonpositive
*/
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;
//将初始容量转为向上最近的2的次方。例如初始为9转为16
this.threshold = tableSizeFor(initialCapacity);
}
第二种设置初始容量,使用默认的加载因子。
/**
* Constructs an empty HashMap with the specified initial
* capacity and the default load factor (0.75).
*
* @param initialCapacity the initial capacity.
* @throws IllegalArgumentException if the initial capacity is negative.
*/
public HashMap(int initialCapacity) {
this(initialCapacity, DEFAULT_LOAD_FACTOR);
}
第三种两个参数都使用默认的设置。初始容量16,加载因子0.75。
/**
* Constructs an empty HashMap with the default initial capacity
* (16) and the default load factor (0.75).
*/
public HashMap() {
this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted
}
构造函数主要完成两个参数的设置,真正初始化散列表是等到添加元素的时候才进行。
HashMap 主要方法
put 方法
/**
* Associates the specified value with the specified key in this map.
* If the map previously contained a mapping for the key, the old
* value is replaced.
*
* @param key key with which the specified value is to be associated
* @param value value to be associated with the specified key
* @return the previous value associated with key, or