面试官,为啥HashMap的长度是2的n次方?
yuyutoo 2024-10-23 16:41 1 浏览 0 评论
前言
HashMap的主干是一个数组,假设我们有3个键值对dnf:1,cf:2,lol:3,每次放的时候会根据hash函数来确定这个键值对应该放在数组的哪个位置,即index = hash(key)
1 = hash(dnf),我们将键值对放在数组下标为1的位置
3 = hash(cf)
1 = hash(lol),这时发现数组下标为1的位置已经有值了,我们就可以用链表的形式将这个键值对放到dnf键值对的下面
1.7 HashMap采用的是头插法,所以lol:3在数组为1的位置,dnf:1以链表的形式跟在lol:3的下面
在获取key为lol的键值对时,1=hash(lol),得到这个键值对在数组下标为1的位置,lol和dnf不相等,和下一个元素比较,相等返回
源码
基于jdk1.7.0_80,1.8和1.7相比 差不多,1.8只是多了一个新特性,当链表的长度>=8的时候,链表转换为红黑树提高查询的效率,1.7解读起来更容易
各种默认参数不再细说,这里说一下threshold和loadFactor,
threshold = capacity * load factor,即扩容的阀值=容量*负载因子,
比如HashMap的容量为16,负载因子为0.75,则阀值为16*0.75=12,
当HashMap中放入12个元素时(size=12),就会进行扩容
1.负载因子越小,容易扩容,浪费空间,但查找效率高
2.负载因子越大,不易扩容,对空间的利用更加充分,查找效率低(链表拉长)
上述中的键值对是存放在一个静态的内部类中,即数组中存放的元素
构造函数只做2件事,初始化数组大小和负载因子,要么自己指定,有么用默认值,可能有人会说threshold是扩容阀值不是数组的长度啊,我们一会细说,(代码省去一部分校验内容)
put操作
这里面试一般会问到为什么HashMap不能存放2个key相等的元素,因为放置key相等的元素时,新值会替换旧值,并且返回旧值
这里我们分析inflateTable,putForNullKey,addEntry方法,hash方法不进行分析,indexFor方法最后进行分析
传入的参数是构造函数初始化的threshold,将数组的长度变为>=size,并且是2的倍数的长度,这样即使初始化数组长度不是2的倍数,也会在第一次放值时变为2的倍数,并且对threshold重新设值
若key为null,则将值放在table[0]这个链上,这样key为null的时候直接从table[0]处取值即可
这里需要注意一下扩容的时机和扩容的大小,以后会和Hashtable,ConcurrentHashMap进行比较
将新增加的元素放到链表的第一位,并且将其他元素跟在第一个元素后面,即头插法
get方法
从table[0]初获取key为null的值
key不为null时
HashMap的大小为什么是2的倍数
h是hashcode,length时数组长度,下面这个方法是根据hashcode求出对象在数组中放置的位置
h & (length - 1) 等价于 h % length,我们假设数组的长度为15和16,hashcide为8和9
可以看出数组长度为15的时候,hash码为8和9的元素被放到数组中的同一个位置形成链表,键低了查询效率,当hahs码和15-1(1110)进行&时,最后一位永远是0,这样0001,0011,0101,1001,1011,0111,1101这些位置永远不会被放置元素,这样会导致1.空间浪费大,2.增加了碰撞的几率,减慢查询的效率。当数组长度为2的n次方时,2的n次方?1的所有位都是1,如8-1=7即111,那么进行低位&运算时,值总与原来的hash值相同,降低了碰撞的概率
相关推荐
- jQuery VS AngularJS 你更钟爱哪个?
-
在这一次的Web开发教程中,我会尽力解答有关于jQuery和AngularJS的两个非常常见的问题,即jQuery和AngularJS之间的区别是什么?也就是说jQueryVSAngularJS?...
- Jquery实时校验,指定长度的「负小数」,小数位未满末尾补0
-
在可以输入【负小数】的输入框获取到焦点时,移除千位分隔符,在输入数据时,实时校验输入内容是否正确,失去焦点后,添加千位分隔符格式化数字。同时小数位未满时末尾补0。HTML代码...
- 如何在pbootCMS前台调用自定义表单?pbootCMS自定义调用代码示例
-
要在pbootCMS前台调用自定义表单,您需要在后台创建表单并为其添加字段,然后在前台模板文件中添加相关代码,如提交按钮和表单验证代码。您还可以自定义表单数据的存储位置、添加文件上传字段、日期选择器、...
- 编程技巧:Jquery实时验证,指定长度的「负小数」
-
为了保障【负小数】的正确性,做成了通过Jquery,在用户端,实时验证指定长度的【负小数】的方法。HTML代码<inputtype="text"class="forc...
- 一篇文章带你用jquery mobile设计颜色拾取器
-
【一、项目背景】现实生活中,我们经常会遇到配色的问题,这个时候去百度一下RGB表。而RGB表只提供相对于的颜色的RGB值而没有可以验证的模块。我们可以通过jquerymobile去设计颜色的拾取器...
- 编程技巧:Jquery实时验证,指定长度的「正小数」
-
为了保障【正小数】的正确性,做成了通过Jquery,在用户端,实时验证指定长度的【正小数】的方法。HTML做成方法<inputtype="text"class="fo...
- jquery.validate检查数组全部验证
-
问题:html中有多个name[],每个参数都要进行验证是否为空,这个时候直接用required:true话,不能全部验证,只要这个数组中有一个有值就可以通过的。解决方法使用addmethod...
- Vue进阶(幺叁肆):npm查看包版本信息
-
第一种方式npmviewjqueryversions这种方式可以查看npm服务器上所有的...
- layui中使用lay-verify进行条件校验
-
一、layui的校验很简单,主要有以下步骤:1.在form表单内加上class="layui-form"2.在提交按钮上加上lay-submit3.在想要校验的标签,加上lay-...
- jQuery是什么?如何使用? jquery是什么功能组件
-
jQuery于2006年1月由JohnResig在BarCampNYC首次发布。它目前由TimmyWilson领导,并由一组开发人员维护。jQuery是一个JavaScript库,它简化了客户...
- django框架的表单form的理解和用法-9
-
表单呈现...
- jquery对上传文件的检测判断 jquery实现文件上传
-
总体思路:在前端使用jquery对上传文件做部分初步的判断,验证通过的文件利用ajaxFileUpload上传到服务器端,并将文件的存储路径保存到数据库。<asp:FileUploadI...
- Nodejs之MEAN栈开发(四)-- form验证及图片上传
-
这一节增加推荐图书的提交和删除功能,来学习node的form提交以及node的图片上传功能。开始之前需要源码同学可以先在git上fork:https://github.com/stoneniqiu/R...
- 大数据开发基础之JAVA jquery 大数据java实战
-
上一篇我们讲解了JAVAscript的基础知识、特点及基本语法以及组成及基本用途,本期就给大家带来了JAVAweb的第二个知识点jquery,大数据开发基础之JAVAjquery,这是本篇文章的主要...
- 推荐四个开源的jQuery可视化表单设计器
-
jquery开源在线表单拖拉设计器formBuilder(推荐)jQueryformBuilder是一个开源的WEB在线html表单设计器,开发人员可以通过拖拉实现一个可视化的表单。支持表单常用控件...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- mybatis plus (70)
- scheduledtask (71)
- css滚动条 (60)
- java学生成绩管理系统 (59)
- 结构体数组 (69)
- databasemetadata (64)
- javastatic (68)
- jsp实用教程 (53)
- fontawesome (57)
- widget开发 (57)
- vb net教程 (62)
- hibernate 教程 (63)
- case语句 (57)
- svn连接 (74)
- directoryindex (69)
- session timeout (58)
- textbox换行 (67)
- extension_dir (64)
- linearlayout (58)
- vba高级教程 (75)
- iframe用法 (58)
- sqlparameter (59)
- trim函数 (59)
- flex布局 (63)
- contextloaderlistener (56)