下面是HashMap的一个构造函数,两个参数initialCapacity,loadFactor

这关系HashMap的迭代性能。

 1     /**
 2      * Constructs an empty <tt>HashMap</tt> with the specified initial
 3      * capacity and load factor.
 4      *
 5      * @param  initialCapacity the initial capacity
 6      * @param  loadFactor      the load factor
 7      * @throws IllegalArgumentException if the initial capacity is negative
 8      *         or the load factor is nonpositive
 9      */
10     public HashMap(int initialCapacity, float loadFactor) {
11         if (initialCapacity < 0)
12             throw new IllegalArgumentException("Illegal initial capacity: " +
13                                                initialCapacity);
14         if (initialCapacity > MAXIMUM_CAPACITY)
15             initialCapacity = MAXIMUM_CAPACITY;
16         if (loadFactor <= 0 || Float.isNaN(loadFactor))
17             throw new IllegalArgumentException("Illegal load factor: " +
18                                                loadFactor);
19         this.loadFactor = loadFactor;
20         this.threshold = tableSizeFor(initialCapacity);
21     }

关于这两个参数值的设定界限:

1. initialCapacity是map的初始化容量,initialCapacity > MAXIMUM_CAPACITY,表明map的最大容量是1<<30,也就是1左移30位,每左移一位乘以2,所以就是1*2^30=1073741824.

2. loadFactor是map的负载因子,loadFactor <= 0 || Float.isNaN(loadFactor),表明负载因子要大于0,且是非无穷大的数字

负载因子为什么会影响HashMap性能

首先回忆HashMap的数据结构,

我们都知道有序数组存储数据,对数据的索引效率都很高,但是插入和删除就会有性能瓶颈(回忆ArrayList),

链表存储数据,要一次比较元素来检索出数据,所以索引效率低,但是插入和删除效率高(回忆LinkedList),

两者取长补短就产生了哈希散列这种存储方式,也就是HashMap的存储逻辑.

而负载因子表示一个散列表的空间的使用程度,有这样一个公式:initailCapacity*loadFactor=HashMap的容量。

所以负载因子越大则散列表的装填程度越高,也就是能容纳更多的元素,元素多了,链表大了,所以此时索引效率就会降低。

反之,负载因子越小则链表中的数据量就越稀疏,此时会对空间造成烂费,但是此时索引效率高。

如何科学设置 initailCapacity,loadFactor的值

HashMap有三个构造函数,可以选用无参构造函数,不进行设置。默认值分别是16和0.75.

官方的建议是initailCapacity设置成2的n次幂,laodFactor根据业务需求,如果迭代性能不是很重要,可以设置大一下。

为什么initailCapacity要设置成2的n次幂,网友解释了,我觉得很对,以下摘自网友博客:深入理解HashMap

左边两组是数组长度为16(2的4次方),右边两组是数组长度为15。两组的hashcode均为8和9,但是很明显,当它们和1110“与”的时候,产生了相同的结果,也就是说它们会定

位到数组中的同一个位置上去,这就产生了碰撞,8和9会被放到同一个链表上,那么查询的时候就需要遍历这个链表,得到8或者9,这样就降低了查询的效率。同时,我们也可以

发现,当数组长度为15的时候,hashcode的值会与14(1110)进行“与”,那么最后一位永远是0,而0001,0011,0101,1001,1011,0111,1101这几个位置永远都不能

存放元素了,空间浪费相当大,更糟的是这种情况中,数组可以使用的位置比数组长度小了很多,这意味着进一步增加了碰撞的几率,减慢了查询的效率!

所以说,当数组长度为2的n次幂的时候,不同的key算得得index相同的几率较小,那么数据在数组上分布就比较均匀,也就是说碰撞的几率小,相对的,查询的时候就不用

遍历某个位置上的链表,这样查询效率也就较高了。

resize()方法

initailCapacity,loadFactor会影响到HashMap扩容。

HashMap每次put操作是都会检查一遍 size(当前容量)>initailCapacity*loadFactor 是否成立。如果不成立则HashMap扩容为以前的两倍(数组扩成两倍),

然后重新计算每个元素在数组中的位置,然后再进行存储。这是一个十分消耗性能的操作。

所以如果能根据业务预估出HashMap的容量,应该在创建的时候指定容量,那么可以避免resize().

转载于:https://www.cnblogs.com/yesiamhere/p/6653135.html

HashMap负载因子相关推荐

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

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

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

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

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

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

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

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

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

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

  6. 什么是加载因子/负载因子/装载因子

    什么是加载因子(负载因子/装载因子)? 用于表示哈希表中元素填满的程度. 冲突的机会越大,则查找的成本越高.反之,查找的成本越低,从而查找的时间越少. HashMap中的加载因子 ①new HashM ...

  7. 哈希 :哈希冲突、负载因子、哈希函数、哈希表、哈希桶

    文章目录 哈希 哈希(散列)函数 常见的哈希函数 字符串哈希函数 哈希冲突 闭散列(开放地址法) 开散列(链地址法/拉链法) 负载因子以及增容 对于闭散列 对于开散列结构 具体实现 哈希表(闭散列) ...

  8. 高级数据结构与算法 | 哈希 :哈希冲突、负载因子、哈希函数、哈希表、哈希桶

    文章目录 哈希 哈希函数 常见的哈希函数 字符串哈希函数 哈希冲突 闭散列的解决方法 开散列的解决方法 负载因子以及增容 对于闭散列 对于开散列结构 具体实现 哈希表(闭散列) 插入 查找 删除 完整 ...

  9. 哈希表的基本概念详解以及具体实现(哈希函数、哈希冲突、负载因子)

    一.哈希表 哈希表是一个典型的用空间换时间的操作,利用数组随机访问的特性,最大化查找效率.哈希过程就是将数组元素与下标建立关系的过程. 二.哈希函数 1.哈希函数的意义: 哈希表是希望将元素与下标建立 ...

最新文章

  1. 带你「周游世界」的 MODNet 算法
  2. ICCV2021|首届城市规模点云语义理解挑战赛启动了
  3. 配置基于Devstack的嵌套KVM虚拟化
  4. PHP array_merge() 函数
  5. [codeVS1204] 单词背诵
  6. Vue+ElemtUI中对el-dialog弹出框宽度调整方法
  7. for ie无效 in js_关于js中for in的缺陷浅析
  8. 服务器挂游戏用什么系统,挂游戏用什么云服务器
  9. Ajax Post请求实例
  10. nagios 监控出现It appears as though you do not have permission
  11. Hibernate一级缓存、二级缓存以及查询缓存的关系
  12. OFD文件预览—前后端两种实现方式
  13. python读取math_python调用通达信公式,python读取通达信公式结果
  14. 职工工资管理系统c语言,C++实现企业职工工资管理系统
  15. feedsky rss更新
  16. 小学计算机写字板教案,小学第二册信息技术《第9课走进“写字板”》教学参考...
  17. 基础操作案例:ArcGIS PRO基础教程(二)
  18. web导出excel文件的几种方法
  19. node.js 不能识别?.问号点运算符
  20. Refused to display in a frame because it set ‘X-Frame-Options‘ to ‘sameorigin‘.

热门文章

  1. java获取文件夹下所有文件的名称
  2. ASP.NET中验证控件的使用
  3. Android TextView里直接显示图片的三种方法
  4. 动态规划算法的优化技巧
  5. golang两种请求http的方式
  6. C#之windows桌面软件第八课:汉字(GB2312)与编码(UTF-8)之间的相互转换
  7. mysql 远程登录权限
  8. 设计模式:装饰者模式(Decorator)
  9. oracle SYS and SYSTEM Schemas
  10. Python 3 教程二:文件,目录和路径