HashMap实现了Map接口,继承AbstractMap。其中Map接口定义了键映射到值的规则,而AbstractMap类提供 Map 接口的骨干实现,以最大限度地减少实现此接口所需的工作。
在这里提到了两个参数:初始容量,加载因子。这两个参数是影响HashMap性能的重要参数,其中容量表示哈希表中桶的数量,初始容量是创建哈希表时的容量,加载因子是哈希表在其容量自动增加之前可以达到多满的一种尺度,它衡量的是一个散列表的空间的使用程度,负载因子越大表示散列表的装填程度越高,反之愈小。对于使用链表法的散列表来说,查找一个元素的平均时间是O(1+a),因此如果负载因子越大,对空间的利用更充分,然而后果是查找效率的降低;如果负载因子太小,那么散列表的数据将过于稀疏,对空间造成严重浪费。系统默认负载因子为0.75,一般情况下我们是无需修改的。
2.2数据存储结构
HashMap是基于哈希表存储“Key-Value”对象应用的数据结构。存入HashMap的键必须具备两个关键函数:
(1)equals():判断两个Key是否相同,用来保证存入的Key的唯一性;
(2)hashCode():genj key-value对象的Key来计算其引用在散列表中存放的位置。
transient Node<K,V>[]
table;
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;
}
}