首页
题库
面试
求职
学习
竞赛
More+
所有博客
搜索面经/职位/试题/公司
搜索
我要招人
去企业版
登录 / 注册
首页
>
试题广场
>
HashMap底层,负载因子,为啥是2^n?
[问答题]
请你解释HashMap的容量为什么是2的n次幂?
添加笔记
求解答(0)
邀请回答
收藏(70)
分享
纠错
8个回答
添加回答
15
zhaoshg
HashMap为了存取高效,要尽量较少碰撞,就是要尽量把数据分配均匀,每个链表长度大致相同,这个实现就在把数据存到哪个链表中的算法; 这个算法实际就是取模,hash%length,计算机中直接求余效率不如位移运算,源码中做了优化hash&(length-1), hash%length==hash&(length-1)的前提是length是2的n次方; 为什么这样能均匀分布减少碰撞呢?2的n次方实际就是1后面n个0,2的n次方-1 实际就是n个1; 例如长度为9时候,3&(9-1)=0 2&(9-1)=0 ,都在0上,碰撞了; 例如长度为8时候,3&(8-1)=3 2&(8-1)=2 ,不同位置上,不碰撞; 其实就是按位“与”的时候,每一位都能 &1 ,也就是和1111……1111111进行与运算
发表于 2019-01-20 22:14:38
回复(0)
3
顶不住也得上啊
一个哈希表,为了减少哈希碰撞,我们首先想到的方法是取余运算,因为取余就可以使得整数均匀地分布到哈希表的每一个位置上。比如现在的哈希表的长度是16,那么11如果要放到哈希表上,那就用11%16,得到了11,那么11就放在索引为11的位置。但是呢,计算机的取余操作效率不高,而位运算的效率是很高的,所以为了提高效率,java的工程师在原码里面就用了x&(length-1)的操作,这里的长度16-1 = 15,11和15做位运算,就是11&(1111),最后得到的结果也是11,也就是说,x&(length-1)的结果是和x%length的结果是一样的,因为当length为2的整数次幂时,length-1的二进制位数上都为1,这样就保证了取余和位运算的结果相等,所以原码为了提高效率就要求长度为2的整数次幂。
发表于 2019-04-12 11:09:22
回复(0)
0
Promote
HashMap的初始容量和扩容都是以2的次方来进行的,目的时为了减少哈希碰撞,提高代码运行效率。
减少哈希碰撞就是尽量让数组的每一个位置下的链表数为相同, 做法:h & (length - 1);length 值为2的次方,length-1换算成二进制的话肯定所有位都为1,就比如2的3次方为8,length-1的二进制表示就是111,所以h& (length-1)运算从数值上来讲其实等价于对length取模,也就是h%length,但是按位与比取模运算效率高。
发表于 2019-08-23 17:09:34
回复(0)
0
西瓜同学🏀
负载因子默认是0.75, 2^n是为了让散列更加均匀,例如出现极端情况都散列在数组中的一个下标,那么hashmap会由O(1)复杂退化为O(n)的。
发表于 2019-05-05 15:08:20
回复(0)
0
TiAmo_9955
负载因子默认是0.75, 2^n是为了让散列更加均匀,例如出现极端情况都散列在数组中的一个下标,那么hashmap会由O(1)复杂退化为O(n)的。
发表于 2019-05-02 18:51:38
回复(0)
0
江畔8670
负载因子默认是0.75, 2^n是为了让散列更加均匀,例如出现极端情况都散列在数组中的一个下标,那么hashmap会由O(1)复杂退化为O(n)的。
发表于 2019-04-29 18:12:35
回复(0)
0
茹(๑•.•๑)
负载因子默认是0.75, 2^n是为了让散列更加均匀,例如出现极端情况都散列在数组中的一个下标,那么hashmap会由O(1)复杂退化为O(n)的。
发表于 2019-04-27 13:36:37
回复(0)
0
每天都说我是过儿
为了在计算哈希值的时候可以不用除留余,直接取模运算,只需要做位运算,效率高
发表于 2019-01-03 20:51:08
回复(0)
这道题你会答吗?花几分钟告诉大家答案吧!
提交观点
问题信息
Java
Java工程师
上传者:
小小
难度:
8条回答
70收藏
7446浏览
热门推荐
相关试题
罗密欧...
操作系统
评论
(1)
下面描述是事务的哪个特性( )已落...
数据库
评论
(1)
在下面的 Verilog 代码片段...
Verilog
评论
(1)
某数据仓库的分区表按日期分区,当执...
Hive
评论
(1)
以下关于C语言中函数指针数组的用法...
C语言
评论
(1)
扫描二维码,关注牛客网
意见反馈
下载牛客APP,随时随地刷题