网站首页 > 教程分享 正文
HashMap是基于哈希表的数据结构实现的集合。底层是由一个Node数组构成的,在jdk1.8之后采用数组+(链表或红黑树)的方式实现。
transient Node<K,V>[] table
node数组的长度在初始化或者扩容(resize)时会被指定,无论怎么变,数组长度始终都是2的n次方。
为什么要是2的n次方?
key在table中的定位是由(length - 1) & hash确定的,length为数组的长度。因为length是2的n次方,所以length-1的二进制肯定是11111....11的形式,此时length-1和hash进行&运算时不会有空间的浪费,且位运算效率很高。假设length不是2的次幂,比如length为15,则 length-1为14,二进制为1110,和hash进行&操作,最后一位都为0,增加了碰撞,使得一些空间被浪费。
总结就是这样做可以减少哈希冲突,均匀分布元素,从代码上来说就是按位“与”的时候,每一位都能&1。
如何保证是2的n次方的?
1)初始化指定容量时,通过tableSizeFor方法返回一个目标容量的2次幂的值(如果目标容量值不是2的n次方,就会返回一个大于该目标值的最小二次幂,如cap为10则返回16)。
2)扩容即resize()得到的新数组长度也是2的n次方。实际数组初始化也是首次put值时通过resize方法完成的。
扩容得到的新数组的长度newCap有三处赋值,可以看到都是2的n次幂。对应图中:1是通过位运算扩容为原长度的2倍;2是hashmap初始化时指定的;3是默认值16。
这里源码中还有个小细节的处理,就是hash()对key的处理并不是只取hashcode。可以说每一个细节都在尽可能的优化,存在必有其原因。
猜你喜欢
- 2024-09-17 c语言 数组(c语言数组定义)
- 2024-09-17 VBA数组与字典解决方案的第17讲:工作表数组大小扩展及意义
- 2024-09-17 Linux编程Shell之入门——Shell获取数组长度
- 2024-09-17 2024-08-28:用go语言,给定一个从1开始、长度为n的整数数组nums
- 2024-09-17 VBA中动态数组的定义及创建(vba 动态)
- 2024-09-17 C语言数组那些事儿,C语言基础教程之数组
- 2024-09-17 一文看懂PG数据类型之数值类型、字符类型、日期类型、数组类型
- 2024-09-17 C语言基础之数组(c语言数组语句)
- 2024-09-17 2023-12-20:用go语言,给定一个数组arr,长度为n,在其中要选两
- 2024-09-17 「清晰易懂」数据结构与算法之数组
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- css导航条 (66)
- sqlinsert (63)
- js提交表单 (60)
- param (62)
- parentelement (65)
- jquery分享 (62)
- check约束 (64)
- curl_init (68)
- sql if语句 (69)
- import (66)
- chmod文件夹 (71)
- clearinterval (71)
- pythonrange (62)
- 数组长度 (61)
- javafx (59)
- 全局消息钩子 (64)
- sort排序 (62)
- jdbc (69)
- php网页源码 (59)
- assert h (69)
- httpclientjar (60)
- postgresql conf (59)
- winform开发 (59)
- mysql数字类型 (71)
- drawimage (61)
本文暂时没有评论,来添加一个吧(●'◡'●)