【952、HashMap的底层了解吗?讲下Hashcode源码?】

26 阅读2分钟

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的性能,减少碰撞。