对HashMap数据结构的理解——加载因子和初始容量

先看源码:
在这里插入图片描述
解释一下位移运算:

1<<4 是位移运算的表示,为十进制16
1的二进制表示:1
左移4位之后的二进制表示为B(10000) = D(16)
更简单的计算方法就是 1<< n 等效于 1 乘以 2的 n 次方

进入正题

HashMap底层数据结构是数组+链表,JDK1.8中还引入了红黑树,当链表长度超过8个时,会将链表转成红黑树,以提升其查找性能。

HashMap有两个参数影响其性能:初始容量和加载因子。

1、HashMap的初始容量

容量是哈希表中桶的数量,初始容量只是哈希表在创建时的容量。

2、HashMap的加载因子

加载因子是哈希表在其容量自动扩容之前可以达到多满的一种度量。

3、作用

当哈希表中的条目数超出了加载因子与当前容量的乘积时,则要对该哈希表进行扩容、rehash操作(即重建内部数据结构),扩容后的哈希表容量为原来的两倍。

为了减少冲突的概率,当HashMap的数组长度到了一个临界值就会触发扩容,把所有元素rehash再放到扩容后的容器中,所以说rehash是一个非常耗时的操作。

而这个临界值是由加载因子和当前容器的容量大小来确定:
DEFAULT_INITIAL_CAPACITY * DEFAULT_LOAD_FACTOR
即默认情况下是 16x0.75 =12 时,就会触发扩容操作。

 /*** Implements Map.put and related methods.** @param hash hash for key* @param key the key* @param value the value to put* @param onlyIfAbsent if true, don't change existing value* @param evict if false, the table is in creation mode.* @return previous value, or null if none*/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)tab[i] = newNode(hash, key, value, null);else {Node<K,V> e; K k;if (p.hash == hash &&((k = p.key) == key || (key != null && key.equals(k))))e = p;else if (p instanceof TreeNode)e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);else {for (int binCount = 0; ; ++binCount) {if ((e = p.next) == null) {p.next = newNode(hash, key, value, null);if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1sttreeifyBin(tab, hash);break;}if (e.hash == hash &&((k = e.key) == key || (key != null && key.equals(k))))break;p = e;}}if (e != null) { // existing mapping for keyV oldValue = e.value;if (!onlyIfAbsent || oldValue == null)e.value = value;afterNodeAccess(e);return oldValue;}}++modCount;if (++size > threshold)resize();afterNodeInsertion(evict);return null;}

4、面试高频:为什么加载因子初始化是0.75呢?

  • 也是一个综合考虑,如果设置过小如0.5,HashMap 每 put 少量的数据,都要进行一次扩容,而扩容操作会消耗大量的性能。使得空间利用率很低,同时提高了rehash(重建内部数据结构)操作的次数。
  • 如果设置过大的话,比如设成1,容量还是16,假设现在数组上已经占用了15个,再要put数据进来,计算数组 index 时,发生 hash碰撞 的概率将达到15/16,这违背了 HashMap 减少 hash碰撞 的原则。同时,这样会减少空间开销,提高空间利用率,但同时会增加查询时间的成本。
  • 因此,选择0.75作为默认的加载因子,完全是时间和空间成本上寻求折中的选择。
  • 在设置初始容量时应该考虑到映射中所需的条目数及其加载因子,以便最大限度地减少rehash操作次数,所以,一般在使用HashMap时建议根据预估值设置初始容量,减少扩容操作。

4、面试高频:为什么初始容量是16

当容量为2的幂次方时,源码中 n -1 对应的二进制数全为1,这样才能保证它和 key 的 hashcode 做&运算后,能够均匀分布,这样才能减少hash碰撞的次数。至于默认值为什么是16,而不是2 、4、8,或者32、64、1024等,应该就是个折中处理,过小会导致放不下几个元素,就要进行扩容了,而扩容是一个很消耗性能的操作。取值过大的话,无疑会浪费更多的内存空间。因此在日常开发中,如果可以预估HashMap会存入节点的数量,则应该在初始化时,指定其容量。

参考原文:
HashMap容量和负载因子:https://blog.csdn.net/ye17186/article/details/88876417
HashMap中的初始容量和加载因子:https://blog.csdn.net/weixin_44723496/article/details/112387738

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/548766.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

“习惯性思维”引起的血案

好久没有更新了&#xff0c;一客户因为IT规划问题&#xff0c;需要将Citrix服务器迁到新的域&#xff0c;Citrix服 务器需要重新配置。但是当我重新配置完站点后&#xff0c;发现无论如何都登录不了。 错误截图&#xff1a; 我按照传统的思路来解决问题&#xff0c; 1、查看服务…

剑指 Offer 52. 两个链表的第一个公共节点

剑指 Offer 52. 两个链表的第一个公共节点 输入两个链表&#xff0c;找出它们的第一个公共节点。 思想&#xff1a;双指针法&#xff0c;浪漫相遇 public static ListNode getIntersectionNode(ListNode headA, ListNode headB) {ListNode pointA headA;ListNode pointB he…

IDEA查看源码时总是出现.class而不是.java源码(解决办法)

自己安装的JDK8里面就有源码&#xff0c;就是图中的src.zip&#xff0c;我还傻乎乎的跑去下。 我参考下面这个链接解决了这个问题&#xff1a; https://www.it610.com/article/1283023085871579136.htm 特别注意其中的一句话&#xff1a;把SDKs中多余的jdk删掉留一个就好&am…

ASP“.NET研究”.NET中的认证与授权

用户认证 .net提供了3种用户认证的方式&#xff0c;分别是Windows,Forms&#xff0c;Passport。这几种形式的定义可以在网站根目录下Web.config中的authentication节点中看见。Windows是默认的验证形式&#xff0c;它是根据机器的访问权限来判断的。Passport是微软提供的一种验…

用NuGet掌管你的Vi“.NET研究”sual Studio扩展

如果你使用Visual Studio 2010&#xff0c;那么 NuGet 可以使你的生活更加美好。当你项目里要引用到的一些库时候&#xff0c;比如JQuery 库或者 NHibernate, NUnit, log4net 你就可以考虑使用NuGet。它可以辅助你安装或者更新这些库。 当然我不得不继续说下去从安装到使用&…

cmd窗口使用python提示“Python not found”,可能是环境变量配置的原因

问题1 打开命令行窗口使用python命令无法直接进入python环境&#xff0c;但是从python的安装目录下就可以进去 问题原因 没有配置系统环境变量&#xff0c;需要把python安装路径添加到path环境变量中 环境变量配置&#xff0c;可以参考菜鸟教程 问题2 配置了环境变量之后…

无法打开caffe.pb.h, no such file or directory错误

问题&#xff1a; 使用VS2013生成caffe解决方案的过程中&#xff0c;出现 无法打开caffe.pb.h&#xff0c;no such file or directory ,解决方案 &#xff1a; 参考博客&#xff1a;[caffe] 无法打开caffe.pb.h, no such file or directory错误 博客地址&#xff1a;https://b…

NuGet Error:Unable to find version ‘0.3.3.0‘ of package ‘glog.overlay-x64_v120_Release_dynamic‘.

问题&#xff1a; 使用VS2013生成caffe解决方案时&#xff0c;报错NuGet Error:Unable to find version 0.3.3.0 of package glog.overlay-x64_v120_Release_dynamic. 解决方案&#xff1a; 一、参考文章里面的回答&#xff1a; 链接&#xff1a;NuGet error while buildin…

【caffe】找不到gpu/mxGPUArray.h

问题原因&#xff1a; Microsoft 的github貌似更新了matcaffe中的caffe_.cpp文件&#xff0c;第十六行添加了对gpu/mxGPUArray.h的引用 解决方法 是将本机Matlab的该文件夹复制到Caffe项目文件的对应位置。 具体方法 在你的matlab文件下面搜索mxGPUArray.h文件&#xff0c…

4 error C2220: 警告被视为错误 - 没有生成“object”文件 (..\..\src\caffe\util\math_functions.cpp)

在VS2013上编译caffe时遇到如下问题&#xff1a; 错误原因&#xff1a; 原因是该文件的代码页为英文&#xff0c;而我们系统中的代码页为中文。 解决方法&#xff1a; 将源码转化为正确的编码方式 用VS2013打开对应的文档&#xff0c;文件->打开->选择该cpp&#xff0…

技术人员如何转型为产品经理

技术人员如何转型为产品经理不知道是不是所有的公司开会都是这样&#xff0c;以时间长短作为衡量会议重要性的标准。周扬被郭姐姐叫去开会&#xff0c;9点半开始&#xff0c;直到快12点了&#xff0c;他才满脸愁容地回到办公室。放下笔记本&#xff0c;周扬站到办公室中间&…

错误 4 error C2220: 警告被视为错误 - 没有生成“object”文件

报错内容&#xff1a; 复制第一行的错误内容&#xff1a; 错误 4 error C2220: 警告被视为错误 - 没有生成“object”文件 D:\Program Files\NugetPackages\boost.1.59.0.0\lib\native\include\boost\format\alt_sstream_impl.hpp 1 1 libcaffe 复制会发现他给出了没有生成obje…

未定义变量或函数caffe_()

该错误是使用matlab 运行classification_demo产生的 三要素仔细检查 一、添加系统环境变量 把 \caffe-master\Build\x64\Release添加到系统环境变量中 二、添加 Caffe 路径 打开 MATLAB&#xff0c;在命令窗口输入pathtool&#xff0c;添加 Caffe 路径&#xff0c;主要是添…

围观窗体与组件03 - 零基础入门学习Delphi25

围观窗体与组件03 让编程改变世界 Change the world by program 围观按钮型组件 Button、BitBtn、SpeedButton的一些区别 区别一&#xff1a;Button 不能显示位图 区别二&#xff1a;SpeedButton 没有焦点&#xff0c;一般用于工具栏按钮 区别三&#xff1a;BitBtn 有 kind…

LaTeX的安装教程及问题记录

安装教程 我的安装过程参考的博客&#xff1a; LaTeX的安装教程&#xff08;Texlive 2020 TeX studio&#xff09; 遇到的问题 TLUtils::install_packages: Failed to install texlive.infra.win32 Installation failed. 解决办法&#xff1a; 将安装包解压路径全部放置在英…

Extra }, or forgotten lendgroup. \makecover

问题&#xff1a; 下载UESTC 的硕士学位论文Latex模板编译后&#xff0c;遇到报错&#xff1a; 产生原因&#xff1a; 问题产生原因&#xff0c;是我偶然间发现&#xff0c;在该语句前面部分的导言区错误表示了&符号。 也就是说&#xff0c;latex中需要注意特殊符号的表…

QTP测试脚本

今天看了QTP参数化写了第一个测试脚本&#xff0c;居然能成功运行了&#xff0c;挺有成就感的&#xff0c;写下来了&#xff0c;嘿嘿……&#xff0c;下面进行详细分析&#xff1a; 转载于:https://www.cnblogs.com/hyzhou/archive/2011/11/11/2245904.html

Undefined control sequence. \makecover

问题&#xff1a; 今天刚下载了github上2021年的UESTC硕士学位论文latex模板&#xff0c;直接编译\makecover报错 产生原因&#xff1a; 在begin{document}前面的内容还缺少字段 解决办法&#xff1a; 添加以下字段 \maintitle \degree 专硕需要把master改成promatesr&am…

Latex的subcaption横向插入两张子图的的用法

用法示例 \begin{figure}[htbp]\centering\subcaptionbox{subtitle1\label{tex2kidliuxiangliang}}{\includegraphics[width6.8cm]{tex2kidliuxiangliang.jpg} }\hfill % 是为了让多幅图在一行均匀分布&#xff08;不加的效果是都挤在中间&#xff09;\subcaptionbox{subtitl…

集中管理:领导者,不能不考虑的几件事之——“挖”出来的无限可能

原文链接&#xff1a;http://www.betasoft.com.cn/laosun/2011-11-14/2054.html 我们都知道&#xff0c;分布式部署管理模式有很多集中管理所无法比拟的优势&#xff0c;但也有其自身所无可避免的缺陷。随着网络基础设施规模和业务规模的扩大&#xff0c;IT运维数据信息的管理和…