zoukankan      html  css  js  c++  java
  • 简述 HashMap 扩容机制

    HashMap基础

    【注意】以下内容只是针对 JDK1.8

    HashMap继承了AbstractMap类,实现了Map,Cloneable,Serializable接口。

    其使用 hash 算法来决定元素的存储,hash 表包含如下属性。

    • 容量(capacity):hash 表数组的大小,默认为16;
    • 初始化容量(initial capacity):创建 hash 表时指定的初始容量;
    • 尺寸(size):当前 hash 表中记录的数量;
    • 负载(load):负载等于 “ size / capacity ”。负载为 0 时,表示空的 hash 表。轻负载的 hash 表具有冲突少、适宜插入和查询的特点。(但太小的话,又会增加占用的内存开销)。
    • 负载因子(load factor):决定 hash 表的最大填满程度,范围是 0~1,默认为 0.75 。

    当 hash 表的负载达到了指定的 “负载因子” 值时,hash 表就会加倍扩容,并将原有的对象重新分配,放入新的表中,这称为 rehashing 。rehashing 过程很复杂,而已非常消耗性能,所以指定一个合适的 “负载因子” 值很重要。

    当 size / capacity > 负载因子,即 size(当前记录数) > 负载因子 * capacity(容量) 时,hash 会扩容。

    HashMap的容量,默认是16

    /**
     * The default initial capacity - MUST be a power of two.
     */
    static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
    

    HashMap的加载因子,默认是0.75

    /**
     * The load factor used when none specified in constructor.
     */
    static final float DEFAULT_LOAD_FACTOR = 0.75f;
    

    当HashMap中元素数超过 容量 * 加载因子 时,HashMap会进行扩容。

    扩容多大?

    HashMap 扩容是为当前容量 * 2,也就是成倍扩容。

    【问题1】为什么每次扩容的倍数是2,而不是1.5或者2.5 ?

    理论上,扩容倍数用多少都行,1.5, 2.5 ,3.5都可以的,都能实现HashMap。

    实际上,HashMap选用了2倍,是为了做一个优化。

    因为计算哈希值的时候是使用取模运算,而HashMap的开发者想要优化下这个取模运算的速度,那么他就需要把HashMap内部的数组长度固定为 2^n 的长度了,也就是说HashMap里面的数组的长度,始终都是2的n次幂。为了实现这个效果,它的扩容因子很自然就是2倍了。

  • 相关阅读:
    47数据结构与算法分析之---查找的基本概念
    46数据结构与算法分析之---排序方法比较
    45数据结构与算法分析之---基数排序
    44数据结构与算法分析之---归并排序
    43数据结构与算法分析之---选择排序
    42数据结构与算法分析之---交换排序
    41数据结构与算法分析之---插入排序
    54数据结构与算法分析之---哈希查找
    40数据结构与算法分析之---排序的基本概念
    37数据结构与算法分析之---关键路径
  • 原文地址:https://www.cnblogs.com/luler/p/15271392.html
Copyright © 2011-2022 走看看