HashMap的扩容机制、初始化容量大小的选择、容量为什么是2的次幂

news2024/12/26 2:48:12

前置知识

先来看看HashMap中的成员属性

解释:

  • size当前的容器中Entry的数量,也就是当前K-V的数量
  • loadFactory装载因子,用来衡量HashMap满的程度,loadFactory的默认值是0.75
  • threshold临界值,当实际KV数量超过threshold时,就会触发扩容机制
    threshold = capatity * loadFactory

容量capatity

除了以上这些成员属性外,还有一个紧密关联的概念:capatity容量。
capatity与size不是同一个概念,size来表示当前的HashMap已经装了多少,capatity是容量,HashMap最多能装多少

利用反射获取HashMap的容量capatity的大小
看好这个方法,接下来要用

public static void printHashMapCapacity(HashMap map) throws Exception {  
    Class<? extends HashMap> mapClass = map.getClass();  
    Method capacity = mapClass.getDeclaredMethod("capacity");  
    capacity.setAccessible(true);  
    Integer invoke = (Integer) capacity.invoke(map);  
    System.out.println(invoke);  
}

如果利用HashMap的无参构造,默认情况下的容量是16,当达到扩容机制时,就会扩容到32,以此类推
如果在new时,指定容量大小,则HashMap会选择第一个大于等于此数字的2的幂次作为初始容量

HashMap<Object, Object> hashMap = new HashMap<>();  
printHashMapCapacity(hashMap);  
// 默认的容量16  
  
HashMap<Object, Object> map2 = new HashMap<>(1);  
printHashMapCapacity(map2);  
// 1 , 因为2的0次方是1  
  
HashMap<Object, Object> map3 = new HashMap<>(7);  
printHashMapCapacity(map3);  
// 8 , 第一个大于7的2的次幂是8

阿里Java开发手册中规定,在初始化HashMap时,应该尽量指定其初始大小

loadFactory和threshold

这两个属性用来指定HashMap的扩容机制
threshold = loadFactory * capacity
当HashMap中的size超过threshold时,就会触发扩容,每次扩容后的容量是原始容量的2倍
从默认的初始容量16扩容到32、64、128…
loadFactory是装载因子,用来衡量HashMap满的程度,默认值是0.75f。
设置成0.75的好处是:capacity是2的次幂,两个数的乘积还是整数,避免浮点数造成影响。
我们初始化HashMap时,除了可以指定初始化容量大小外,还可以指定装载因子的大小的,但是修改装载因子的值是不推荐的。

为什么要设置初始化容量

当HashMap 发生扩容时,会新建一个指定容量的桶,然后将原来的Entry拷贝到新的桶中。
此过程会有较大的资源消耗。
为了避免在向HashMap中put过多元素时频繁发生扩容,需要指定一个合适大小的初始化容量。

初始化容量设置多少合适

我们的目的是避免频繁发生扩容,所以一次性指定初始化容量合适大小。
并不是我要塞入多少个元素,就初始化为多少,来看一个例子:
当我要向HashMap中put 7个元素,我将HashMap初始化为7

HashMap map = new HashMap(7);

因为传入的是一个7,HashMap会选择一个大于等于该值的2的次幂作为容量capacity
根据loadFactory=0.75,计算出threshold = 8 * 0.75 = 6
当我们put第7个元素时,就会触发扩容,扩容到16。
但是我们就想put 7个元素,在第7个时触发扩容,导致了性能和空间的浪费。
所以,我们在初始化时,选择多少的初始化容量,值得考虑。

借鉴HashMap 中putAll()方法,得出以下公式:

initCapatity = expectedSize / 0.75F + 1.0F 

这个计算方法虽然浪费了一些空间,但是在性能上却提升了。
当我们要put 7个元素, initCapacity = 7 / 0.75 + 1 = 10 ,经过HashMap的计算,第一个大于10的2的次幂的数是16,所以HashMap的容量是16。
16 * 0.75 = 12 ,当我要put第7个元素时,并不会发生扩容,性能得到提升。
而且与第一次我们设置初始化容量为7相比,最终所占用的空间是一样的。

为什么选择2的次幂作为容量

因为,在put时,HashMap会根据key的hash来计算对应Entry所在桶的位置。
通常都是利用求余来实现的

index = hash % capacity

但是直接利用%来计算是非常慢的,效率非常第低。
我们知道,在计算机中,最快的运算就是位运算了。
存在这样一个规律:当capacity是2的次幂时,满足以下恒等式

hash % capacity == hash & (capacity - 1)

在我们创建HashMap时,就做了第一步处理,选择大于等于给定数字的第一个2的次幂作为容量,就保证了。

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

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

相关文章

ChatGPT实现语义分析情感分类

语义分析情感分类 我们从开源社区找到了中科院谭松波博士整理的携程网酒店评论数据集(https://raw.githubusercontent.com/SophonPlus/ChineseNlpCorpus/master/datasets/ChnSentiCorp_htl_all/ChnSentiCorp_htl_all.csv)。一共七千余条数据&#xff0c;包括 label 和 review …

Domino中的时间日期格式设置

大家好&#xff0c;才是真的好。 今天我们谈管理运维问题&#xff0c;相对于前面的技术来说&#xff0c;会简单很多。 就是Domino服务器运行时的时间日期显示问题。这和你的邮件、应用等里面的文档时间日期也有关系。 简单来说&#xff0c;在默认的设置情况下&#xff0c;Do…

java——最小的K个数

题目链接 牛客在线oj题——最小的K个数 题目描述 给定一个长度为 n 的可能有重复值的数组&#xff0c;找出其中不去重的最小的 k 个数。例如数组元素是4,5,1,6,2,7,3,8这8个数字&#xff0c;则最小的4个数字是1,2,3,4(任意顺序皆可)。 数据范围&#xff1a;0≤k,n≤10000&…

【刷题之路】LeetCode 206. 反转链表

【刷题之路】LeetCode 206. 反转链表 一、题目描述二、解题1、方法1——改变指针方向1.1、思路分析1.2、代码实现 2、方法2——头插到新链表2.1、思路分析2.2、代码实现 一、题目描述 原题连接&#xff1a; 206. 反转链表 题目描述&#xff1a; 给你单链表的头节点 head &…

4月26号软件更新资讯合集....

Tpflow V7.0.2&#xff0c;PHP 工作流引擎新版发布 ​欢迎使用 Tpflow V7.0.1 工作流引擎 TpFlow 工作流引擎是一套规范化的流程管理系统&#xff0c;基于业务而驱动系统生命力的一套引擎。彻底释放整个信息管理系统的的活力&#xff0c;让系统更具可用性&#xff0c;智能应用型…

设计模式天花板,详解23种设计模式+7大设计原则

这份文档完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起&#xff0c;包括每个模式的定义、功能、思路、结构、基本实现、运行调用顺序、基本应用示例等&#xff0c;让读者能系统、完整、准确地掌握每个模式&#xff0c;培养正确的“设计观”;中高级内容则深…

速速报名| 米尔将精彩亮相2023 STM32中国峰会暨粉丝狂欢节

STM32峰会已成功举办五届&#xff0c;第六届将于今年5月12日-13日在深圳重磅回归&#xff01;往年&#xff0c;米尔电子都作为官方合作伙伴&#xff0c;出席演讲并展出公司配套的核心板和开发板。 今年&#xff0c;STM32峰会更是集齐了值得你「点赞、收藏、转发」的一键三连精…

漫画 | Linux之父:财务自由以后,我失眠了!

前言&#xff1a;今年是Linux诞生的30周年&#xff01; 1991年的8月&#xff0c; Linus在新闻组中公布了他正在开发的一个免费的操作系统&#xff0c;这也是以后风靡世界的Linux操作系统的雏形。 今天翻到这篇漫画&#xff0c;看到Linux的诞生过程&#xff0c;很是感慨&#x…

FPGA实现10G万兆网UDP通信 10G Ethernet Subsystem替代网络PHY芯片 提供工程源码和技术支持

目录 1、前言2、我这里已有的UDP方案3、详细设计方案传统 FPGA UDP 方案本 FPGA 10G UDP 方案(牛逼)10G Ethernet 框图10G Ethernet 发送解析10G Ethernet 接收解析10G Ethernet 寄存器配置10G Ethernet UI 配置 4、vivado工程详解5、上板调试验证并演示ping功能测试数据收发测…

新手必看:蓝牙耳机什么牌子的好用?2023年蓝牙耳机排名

上班通勤、健身运动、游戏娱乐都离不开蓝牙耳机&#xff0c;蓝牙耳机市场这几年逐渐饱和&#xff0c;涌现了大量的品牌&#xff0c;蓝牙耳机什么牌子的好用成为热议话题&#xff0c;新手们在挑选时会参考排行榜&#xff0c;小编接下来将盘点2023年蓝牙耳机排名。 ●JEET Air 2蓝…

【服务器数据恢复】HP MSA存储raid5数据恢复案例

服务器故障环境&#xff1a; HP MSA某型号存储&#xff0c;8块SAS的硬盘组建RAID5磁盘阵列&#xff0c;其中包括1块热备盘。故障存储中基于该RAID组的LUN均分配给HP-Unix小机使用&#xff0c;上层做的LVM逻辑卷&#xff0c;存储的数据为Oracle数据库及OA服务端。 服务器故障&a…

PyCharm更换pip源、模块安装、PyCharm依赖包导入导出

一、Pycharm更换安装源 在下载安装好Pycharm后&#xff0c;一个在实际编程开发过程中非常重要的问题是第三方库添加&#xff0c;然而Python默认的源网络速度有点慢&#xff0c;因此&#xff0c;我们常常需要做的是更换Pycharm的安装源。 在当前最新版&#xff08;2022.03版&…

[排序算法]桶排序

参考&#xff1a;《漫画算法-小灰的算法之旅》 目录 一、什么是桶排序 二、桶排序的工作原理 三、代码 四、时间复杂度和空间复杂度 一、什么是桶排序 桶排序是一种线性时间的排序算法&#xff0c;它类似于基数排序所创建的统计数组。桶排序需要创建若干个桶来协助排序。 …

企业数字化管理中,数据治理到底怎么“治”

随着信息化、数字化的理念、技术及其应用在社会的方方面面进行扩散&#xff0c;数据的规模和丰富程度已经达到了一个新的高度&#xff0c;所以当下如何更进一步利用好数据&#xff0c;充分发挥数据的价值&#xff0c;将其真正变为高质量的数据资产成为了企业要面对的重要问题&a…

Matlab高光谱遥感、数据处理与混合像元分解及典型案例

站在学员的角度去理解“高光谱”&#xff0c;用大家能听的懂的语言去讲述高光谱的基本概念和理论&#xff0c;帮助学员深入理解这项技术的底层科学机理。方法篇&#xff0c;将高光谱技术与MATLAB工具结合起来&#xff0c;采用MATLAB丰富的工具箱&#xff0c;快速复现高光谱数据…

爱快 Docker NodeRed Tcp服务器远程连接试验

有一台基于4415软路由安装的ubuntu server系统&#xff0c;在Ubuntu上通过Docker安装了NodeRed。ubuntu通过爱快硬路由与外网连接。爱快硬路由通过动态域名和端口映射实现远程访问ubuntu。 平时通过如下命令运行NodeRed镜像&#xff1a; docker run -it --rm -e TZ"Asia/…

掌握这些Revit常见术语,从此BIM建模再无压力

BIM模型看似复杂&#xff0c;其实只要掌握模型中基本元素的概念&#xff0c;理清建模原理&#xff0c;就能轻松上手&#xff0c;游刃有余。 首先&#xff0c;我们要清楚&#xff0c;作为BIM主要建模软件的Revit&#xff0c;可以在三维空间中建立起数字化的建筑信息模型&#xf…

【更新公告】AirtestIDE更新至1.2.15版本

1. 前言 本次更新为AirtestIDE、Airtest、Poco、iOS-tagent更新。 AirtestIDE更新至1.2.15版本&#xff0c;Airtest更新为1.2.10版本&#xff0c;Poco更新为1.0.89版本&#xff0c;iOS-tagent重新梳理了master分支内容。更新内容详见下文。 2. 更新内容 1&#xff09;Airte…

HBase之全文检索Phoenix

HBase高手之路6-HBase之全文检索Phoenix 一、全文检索 ​ 二、全文检索工具phoenix简介 三、OLTP和OLAP 1. OLAP 在线分析处理系统&#xff0c;hadoop、hbase、hive提供支持 2. OLTP 在线事务处理系统&#xff0c;传统的关系数据库支持 四、Phoenix的安装 1. 下载 2.…

企业数字化转型的核心是什么?如何才能真正做到数字化转型?

什么是数字化转型&#xff1f;如何才能做到数字化转型&#xff1f; 好像大家一直在讨论&#xff0c;但仍然没有一个明确的答案。 这其实很正常: 因为“数字化”一词对不同的企业来说有不同含义。它可以是从采用新技术——引入自动化操作中的任何一样东西。此外&#xff0c;“…