HashMap是Java中常用的集合类之一,它基于哈希表实现,用于存储键-值对。HashMap的底层数据结构主要包括数组和链表(Java 8及之后版本还引入了红黑树用于解决哈希冲突),其中数组用来存储哈希桶,每个桶可以包含多个键-值对。在Java 8之后,HashMap也支持了存储顺序,因此还包括了一个指向双向链表的指针。
以下是HashMap的主要成员变量和关键方法:
Node<K, V>[] table
: 存储键-值对的数组桶。int size
: 存储HashMap中键-值对的数量。int threshold
: 用于控制哈希表扩容的阈值。float loadFactor
: 决定何时进行扩容的加载因子。Node<K, V> head
: 链表的头部。Node<K, V> tail
: 链表的尾部。
Hashcode(哈希码)是用于将键映射到哈希桶的整数值。在HashMap中,每个键都会有一个对应的哈希码,它通过键对象的hashCode()
方法生成。HashMap会使用哈希码对桶的索引进行计算,以确定键-值对应该存储在哪个桶中。
下面是Java 8中HashMap的hashCode()
方法的源码:
public int hashCode() {
int h = hash;
if (h == 0 && key.length() > 0) {
char val[] = key.value;
for (int i = 0; i < key.length(); i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
}
在这个源码中,hash
是HashMap中存储的哈希码,如果为0,表示还没有计算过哈希码。它通过遍历键的字符数组,将每个字符的哈希值乘以31,然后加上之前的哈希值,最终生成键的哈希码。这个方法确保了对于相同的键,它们生成的哈希码是相同的。
注意,为了减小哈希冲突的可能性,HashMap中的哈希码是通过将键的哈希码与一个位运算操作得到的,以便让键在哈希表中均匀分布。这有助于提高HashMap的性能,减少碰撞。