https://blog.csdn.net/dengbixuan/article/details/104767065

为什么HashMap的负载因子设置成0.75,而不是1也不是0.5?这背后到底有什么考虑?

在HashMap源码中 HashMap默认容量大小是16,最大容量是2的30次方,默认的负载因子是0.75f;

static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16

static final int MAXIMUM_CAPACITY = 1 << 30;

static final float DEFAULT_LOAD_FACTOR = 0.75f;

1. 什么是负载因子?
     负载因子(loadFactor)表示HashMap满的程度,默认值为0.75f,也就是说默认情况下,当HashMap中元素个数达到了容量的3/4的时候就会进行自动扩容。

第一次创建HashMap的时候,就会指定其容量(如果未明确指定,默认是16)。随着我们不断的向HashMap中put元素的时候,就有可能会超过一定的阈值,那么就需要有一个扩容机制。所谓扩容,就是扩大HashMap的容量(JDK1.8):

final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
                   boolean evict) {
        Node<K,V>[] tab; Node<K,V> p; int n, i;
        if ((tab = table) == null || (n = tab.length) == 0)
            n = (tab = resize()).length;
        if ((p = tab[i = (n - 1) & hash]) == null)
        .......
        ++modCount;
        if (++size > threshold)
            resize();
        afterNodeInsertion(evict);
        return null;
    }

从代码中我们可以看到,在向HashMap中添加元素过程中,如果 元素个数(size)超过临界值(threshold) 的时候,就会进行自动扩容(resize),并且,在扩容之后,还需要对HashMap中原有元素进行rehash,即将原来桶中的元素重新分配到新的桶中。

在HashMap中,临界值(threshold) = 负载因子(loadFactor) * 容量(capacity)。

2. 为什么要扩容?
    HashMap在扩容到过程中不仅要对其容量进行扩充,还需要进行rehash!所以,这个过程其实是很耗时的,并且Map中元素越多越耗时。rehash的过程相当于对其中所有的元素重新做一遍hash,重新计算要分配到那个桶中。

HashMap 是一个数组加链表的结构,不扩容也是可以无限存储的,为什么要扩容?

扩容是为解决哈希冲突问题。HashMap其实是底层基于哈希函数实现的,但是哈希函数都有如下一个基本特性:根据同一哈希函数计算出的哈希值如果不同,那么输入值肯定也不同。但是,根据同一哈希函数计算出的哈希值如果相同,输入值不一定相同。两个不同的输入值,根据同一哈希函数计算出的哈希值相同的现象叫做碰撞。

HashMap将数组和链表(或者红黑树)组合在一起,发挥了两者的优势,我们可以将其理解为链表的数组。但是,如果一个HashMap中冲突太高,那么数组的链表就会退化为链表。这时候查询速度会大大降低。

为了解决哈希冲突问题,在合适的时候扩大数组容量,再通过一个合适的hash算法计算元素分配到哪个数组中,就可以大大的减少冲突的概率。就能避免查询效率低下的问题。

3.为什么默认loadFactor是0.75?
   为了避免哈希碰撞,HashMap需要在合适的时候进行扩容。那就是当其中的元素个数达到临界值的时候,而这个临界值前面说过和loadFactor有关,换句话说,设置一个合理的loadFactor,可以有效的避免哈希冲突。

关于loadFactor在JDK官方文档里有说明:一般来说,默认的负载因子(0.75)在时间和空间成本之间提供了很好的权衡。更高的值减少了空间开销,但增加了查找成本(反映在HashMap类的大多数操作中,包括get和put)。

试想一下,如果我们把负载因子设置成1,容量使用默认初始值16,那么表示一个HashMap需要在"满了"之后才会进行扩容。那么在HashMap中,最好的情况是这16个元素通过hash算法之后分别落到了16个不同的桶中,否则就必然发生哈希碰撞。而且随着元素越多,哈希碰撞的概率越大,查找速度也会越低。

如果负载因子设置为0.5,那么就会频繁的扩容,浪费空间。

loadFactor=0.75科学依据

a .根据数学公式推算。负载因子为log(2)的时候,可以既减少哈希冲突,又浪费空间,是时间和空间的权衡。

log(2)大约为0.7。

b.根据HashMap的扩容机制,应该保证capacity的值永远都是2的幂。

为了保证负载因子(loadFactor) * 容量(capacity)的结果是一个整数,这个值是0.75(3/4)比较合理,因为这个数和任何2的幂乘积结果都是整数。

参考:https://mp.weixin.qq.com/s/_zbOHbQa2zDVosXUlYUrSQ

hashmap的负载因子为什么是0.75而不是其他值或者1相关推荐

  1. 为什么 HashMap 加载因子一定是0.75?而不是0.8,0.6?

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 有很多东西之前在学的时候没怎么注意,笔者也是在重温HashMap的 ...

  2. 面试中对hashMap的再次理解,负载因子为什么为0.75

    2019独角兽企业重金招聘Python工程师标准>>> 见博客 http://blog.csdn.net/a_long_/article/details/51594159 看图就可以 ...

  3. 原创 | 我说我了解集合类,面试官竟然问我为啥HashMap的负载因子不设置成1!?...

    △Hollis, 一个对Coding有着独特追求的人△ 这是Hollis的第 254篇原创分享 作者 l Hollis 来源 l Hollis(ID:hollischuang) 在Java基础中,集合 ...

  4. 我说我了解集合类,面试官竟然问我为啥HashMap的负载因子不设置成1!?

    在Java基础中,集合类是很关键的一块知识点,也是日常开发的时候经常会用到的.比如List.Map这些在代码中也是很常见的. 个人认为,关于HashMap的实现,JDK的工程师其实是做了很多优化的,要 ...

  5. 为什么 HashMap 默认加载因子非得是0.75?

    点击上方 "编程技术圈"关注, 星标或置顶一起成长 后台回复"大礼包"有惊喜礼包! 每日英文 Sometimes,God does not give you w ...

  6. HashMap的负载因子为什么默认是0.75

    作用 负载因子是和扩容机制有关的,意思是如果当前容器的容量,达到了我们设定的最大值,就要开始执行扩容操作.比如说当前的容器容量是16,负载因子是0.75,16*0.75=12,也就是说,当容量达到了1 ...

  7. HashMap的负载因子初始值为什么是0.75?这篇文章以最通俗的方式告诉你答案

    之前写过一篇专门介绍HashMap的文章,反响很不错,不过在留言区问的最多的问题就是HashMap的负载因子初始值为什么是0.75,私下又好好地研究了一番,总结了这篇文章. 本篇文章基于JDK1.8, ...

  8. HashMap中负载因子的意义是什么?

    学习记录 HashMap中负载因子的意义是什么? HashMap具有两个重要属性: size 和 load factor HashMap的实例具有两个影响其性能的参数:初始容量(0.75f)和负载因子 ...

  9. element 往node里面增加属性值_HashMap加载因子为何0.75,为何初始化值2的指数幂,底层解析...

    01 前言 我们在声名HashMap的时候,一般都会这样写. public class MapTest { public static void main(String[] args) { HashM ...

  10. 为什么 HashMap 的加载因子是0.75?

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 来源 | https://blog.csdn.net/N ...

最新文章

  1. HSV(HSL)颜色空间及其应用
  2. 8. An Introduction to MCMC for Machine Learning (4)
  3. python地理数据处理 下载_python-doc/将Python用于地理空间数据处理.md at master · zhuxinyizhizun/python-doc · GitHub...
  4. MySQL 5.1 安装过程中报apply security setting错误的解决办法 收藏
  5. matlab_ga(),matlab遗传算法ga函数
  6. Android 常用的数据加密方式
  7. ELK和EFK的区别
  8. typecho支持html,[分享] Basic HTML - 一款极简的Typecho主题
  9. SUDTOJ 3323园艺问题 (线段树)
  10. oracle服务器文件有哪些,Oracle服务器参数文件维护的技巧有哪些呢?
  11. 视觉SLAM十四讲学习笔记——第五讲--相机与图像
  12. 提升效率Mysql函数(function)|存储过程(procedure)
  13. 用力和应变片计算弹性模量_电阻应变片粘贴及弹性模量的测定实验报告徐姗.doc...
  14. 【Webex】加入会议是无法正常加入!提示“下载会议组件时无法获取正确的参数。 请联系技术支持以获取帮助。...
  15. 使用html查看dicom,LEADTOOLS构建HTML5 DICOM/PACS查看器(二)
  16. arcgis engine已知图幅号获取比例尺
  17. 关于Dr.Com3.73多人上网的破解(一)
  18. Ubantu系统中安装360Wifi步骤
  19. jsonDB使用手冊
  20. FTXUI基础笔记(botton按钮组件基础)

热门文章

  1. LOJ6504 「雅礼集训 2018 Day5」Convex 凸包、莫队
  2. windows全部启动项
  3. 天津东软实训第八天------倒排索引
  4. 排序算法——直接选择排序
  5. 【远程重启】使用windows自带的shutdown命令远程重启服务器(测试不行,此文作废)...
  6. Spring4学习笔记 - Bean的生命周期
  7. 从3dmax导出动画总结
  8. 用CSS hack技术解决浏览器兼容性问题
  9. 091 类的多态和多态性
  10. 查找Ubuntu下包的归属