使用容量 10000 的HashMap 存9000条数据,会触发扩容吗 ?

导读:本篇文章讲解 使用容量 10000 的HashMap 存9000条数据,会触发扩容吗 ?,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

面试官:使用容量 10000 的HashMap 存9000条数据,会触发扩容吗 ?

先说结论,不会!

众所周知,Hashmap有负载因子为0.75,达到负载因子就会触发扩容,但这是无参构造即初始容量为16的Hashmap,而这里容量是10000,使用了有参构造的Hashmap,不一样。
在这里插入图片描述

1. 源码分析

在 HashMap 中,提供了一个指定初始容量的构造方法 HashMap(int initialCapacity),这个方法再通过 DEFAULT_LOAD_FACTOR 调用 HashMap 另一个重载的构造方法,初始化 loadFactor 为 0.75;

public HashMap(int initialCapacity) {
    this(initialCapacity, DEFAULT_LOAD_FACTOR);
}
public HashMap(int initialCapacity, float loadFactor) {
  	......
    this.loadFactor = loadFactor;
    this.threshold = tableSizeFor(initialCapacity);;

构造方法初始化了两个成员变量 thresholdloadFactor,其中 threshold 就是用来存储触发 HashMap 扩容的阈值,也就是说,当 HashMap 存储的数据量达到 threshold 时,就会触发扩容!

从构造方法中可以看出,threshold 并没有直接使用传入的 initialCapacity 作为扩容阈值,而是通过 tableSizeFor 方法处理后再赋值给 threshold。

static final int tableSizeFor(int cap) {
    int n = cap - 1;
    n |= n >>> 1;
    n |= n >>> 2;
    n |= n >>> 4;
    n |= n >>> 8;
    n |= n >>> 16;
    return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
}

tableSizeFor 的作用就是寻找大于 initialCapacity 的 2 的整数次方,例如如果传入 10,经过 tableSizeFor 处理后返回 16,而此时传的是10000,10000并不是2的n次方倍,

如果从传进来参数是 10000作为initialCapacity ,实际上经过 tableSizeFor 方法处理之后,最终 threshold 就会变成 2 的 14 次幂 16384,再在 resize 方法中乘上负载因子 0.75,实际在不触发扩容的前提下,可存储的数据容量是 12288(16384 * 0.75),用来存放 9000条数据,不会触发扩容。

2. 总结

  1. 使用10000作为 initialCapacity 传入有参的HashMap构造方法,会调用重载的构造方法,初始化 loadFactorthrehold

  2. threhold 就是扩容的阀值,即当HashMap的size达到阀值就会扩容;

  3. 但是threhold不是直接将传入的参数 x 0.75,而是再调用 tableSizeFor来处理传入的参数,因为10000不是2的整数次方!

    所以10000 会变为2的14次方再 x 0.75,结果threhold大于10000,所以put 9000条数据不会触发扩容!

参考:
https://blog.csdn.net/Acx77/article/details/122692412
https://blog.csdn.net/qq_46548855/article/details/125900393

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/89163.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!