Java中HashMap是如何进行扩容的?

HashMap是如何进行扩容的,初始化是多少,假设有1000个元素放入hashmap中,初始化多大,默认值是多少,过程是什么?

HashMap底层原理:底层是数组+链表+红黑树

其扩容流程:

  1. 首先,HashMap中的table数组会在第一次往HashMap中put元素的时候进行初始化,如果HashMap初始化的时候没有指定容量,那么初始化table数组的时候会使用默认的DEFAULT_INITIAL_CAPACITY参数,也就是16,来作为table数组的初始化的长度。

  2. 如果在初始化HashMap的时候指定了容量的话,HashMap会把这个容量修改为2的幂次方,然后创建对应长度的table数组。至于为什么要将容量修改为2的幂次方,后面说。

  3. 当数组中元素的个数超过 CAPACITY(数组的大小) DEFAULT_LOAD_FACTOR(0.75)* 时,HashMap中的table就会发生扩容,其容量会扩大一倍,也就是 2*CAPACITY,扩容之后,HashMap会重新计算每个元素在数组中的位置。

    为什么加载因子默认为0.75? 因为0.75是对空间和时间效率的一个公平的选择,根据泊松分布,加载因子取为0.75的时候碰撞是最小的,一般都会使用默认值。如果在时间和空间比较特殊的情况之下,需要修改加载因子,保持以下原则:

    • 如果内存空间很大,并且对时间效率要求很高,可以降低LOAD_FACTOR的值。
    • 如果内存很紧张,并且对时间效率要求不是很高,可以增加LOAD_FACTOR的值,并且这个值可以大于1。

    举例说明: 假如需要存100个元素到HashMap中,并且使用HashMap默认初始化容量,其过程如下:

    1. 首先初始化table为16,然后插入元素。
    2. 当table数组中的元素个数大于 16 * 0.75=12时,table会发生扩容操作,其容量变为16 * 2 = 32。
    3. 然后继续重复插入,直至将所有的元素加入的table中。

总结:

如果在初始化时没有指定HashMap的容量,HashMap会在插入数据时会不断的扩容,扩容条件是当元素的个数超过临界时的时候(threshold = loadFactor * capacity)

如果没有设置HashMap的容量,随着元素的不断增加,HaahMap会发生多次的扩容,而每次HashMap扩容之后都会重新计算元素的位置,也就是需要重建Hash表,非常的影响性能,所以建议在创建HashMap的时候指定HashMap的容量。

例如: 假设要向HashMap中存入1000个元素,需要指定HashMap的容量为2048,而不是1024,因为HashMap扩容条件临界值是threshold = loadFactor * capacity,也就是1000*0.75=750,也就是超过750之后,HashMap就会发生扩容。

你可能感兴趣的:(学习总结,java,数据结构,哈希算法)