欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

了解 HashMap 数据结构,超级详细!-4, 为什么 HashMap 数组的长度是 2 的幂次?

最编程 2024-03-02 18:19:54
...

我们先看看它的成员变量:

序列化版本号

private static final long serialVersionUID = 362498820763181265L;

集合的初始化容量initCapacity

//默认的初始容量是16 -- 1<<4相当于1*2的4次方---1*16
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4;   

初始化容量默认是16,容量过大,遍历时会减慢速度,效率低;容量过小,那么扩容的次数变多,非常耗费性能。

负载因子

/**
     * The load factor used when none specified in constructor.
     */

    static final float DEFAULT_LOAD_FACTOR = 0.75f;

初始默认值为0.75,若过大,会导致哈希冲突的可能性更大;若过小,扩容的次数也会提高。

为什么必须是2的n次幂?

当向HashMap中添加一个元素的时候,需要根据key的hash值,去确定其在数组中的具体位置。HashMap为了提高存取效率,要尽量较少碰撞,就是要尽量把数据分配均匀,每个链表长度大致相同,这个实现就在把数据存到哪个链表中的算法。

这个算法实际就是取模,hash%length,计算机中直接求余效率不如位移运算。所以源码中做了优化,使用 hash&(length-1),而实际上hash%length等于hash&(length-1)的前提是length是2的n次幂。

如果输入值不是2的幂会怎么样?

如果数组长度不是2的n次幂,计算出的索引特别容易相同,及其容易发生hash碰撞,导致其余数组空间很大程度上并没有存储数据,链表或者红黑树过长,效率降低。

小结:

1,当根据key的hash确定其在数组的位置时,如果n为2的幂次方可以保证数据的均匀插入,如果n不是2的幂次方,可能数组的一些位置永远不会插入数据,浪费数组的空间,加大hash冲突。

2,一般可能会想通过 % 求余来确定位置,这样也可以,只不过性能不如 & 运算。而且当n是2的幂次方时:hash & (length - 1) == hash % length

3,因此,HashMap 容量为2次幂的原因,就是为了数据的的均匀分布,减少hash冲突,毕竟hash冲突越大,代表数组中一个链的长度越大,这样的话会降低hashmap的性能


好了,今天就先分享到这里了,下期继续给大家带来HashMap面试内容!更多干货、优质文章,欢迎关注我的原创技术公众号~