HashMap究极详细
HashMap底层详解
1.简介
HashMap是java种使用频繁的数据结构,其储存对象是无序的,以key,value的形式存放
1.key可以为null
2.key不能重复,如果key重复则会覆盖第一个key的value
3.一个key,对应一个value
2.HashMap的常用方法
方法 | 解释 |
---|---|
put(key,value) | 存入一对键值对key,value,如果key已存在则用这个value覆盖掉以前的,不存在则加入 |
get(key) | 通过key来获取值 |
values() | 获得所有的value |
keySet() | 获得所有的key |
isEmpty() | 判断是否为空 |
putAll(map) | 把另一个map全部加入这个map |
containsKey(key) | 判断map种是否包含这个key |
containsValue(value) | 判断map中是否包含这个value |
size() | map的长度 |
3.底层数据结构
hashMap底层的数据结构是以数组和链表的形式。
数组:查找快
链表:增删快
这也是设计成数组+链表的原因
底层的数组默认长度为16,随着map长度的加大可能会扩容,当链表变长的时候链表的数据结构也会变
以及为什莫数组默认长度为16?(下面会一 一陈述)
HashMap储存对象时:***key所属的类***必须重写Object类里的HashCode()和equals()
HashCode():会为每个对象产生一个Hash值。 保证了高效性
equals():根据hash值判断两个对象是否一样,Hash值不一样两个***一定不相等***有
时可能会有两个对象Hash值相等但值不一样,这时候要调用equals()比对两个对
象是否真的一致(保证key不重复)。 保证了准确性
4.Hash冲突
1.存入对象时,先算出其的Hash值然后和数组的长度求余也就是(Hash%16)算出来的值就是其存在的数组位数。
2.如果这一位已经有对象了那么就往下面链表里坠,next直到下一个为空,则把这个对象放到这。
5.Hash容量以及扩容机制
1.负载因子
HashMap中有一个默认负载因子为0.75
为什莫为默认负载因子0.75?
① 阈值=负载因子容量*容量为2的幂次方所以必须保证
容量*负载因子为整数
② 负载因子越大Hash冲突越多,负载因子越少,空间浪费越大,权衡得出结果
2.扩容机制
当元素数量大于阈值则需要扩容,将数组长度按位向左移一位
由于:计算机底层按位移操作快(乘法的底层为加法效率不高)
HashMap的容量是有上限的,必须小于1<<30,即1073741824。如果容量超出了这个数,则不再增长,且阈值会被设置为 Integer.MAX_VALUE( [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7P6Ksaik-1626959298692)(https://www.zhihu.com/equation?tex=2%5E%7B31%7D-1)] ),即永远不会超出阈值了)。
3.HashMap的数组开始长度为什莫为16
首先我们看hashMap的源码可知当新put一个数据时会进行计算位于table数组(也称为桶)中的下标:
int index =key.hashCode()&(length-1);
hashmap每次扩容都是以 2的整数次幂进行扩容
比如: 十进制: 201314
二进制: 11 0001 0010 0110 0010
假设初始化大小为16
15转化为二进制: 1111
index : 11 0001 0010 0110 0010 & 1111 =0010 为 3
因为是将二进制进行按位于,(16-1) 是 1111,末位是1,这样也能保证计算后的index既可以是奇数也可以是偶数,并且只要传进来的key足够分散,均匀那么按位于的时候获得的index就会减少重复,这样也就减少了hash的碰撞以及hashMap的查询效率。
这样看起来2的n次方都可以,但8和4太小,Hash碰撞太多,32太大故选16
6.HashMap中的扰动函数
什么为扰动函数?
static final int hash(Object key) {int h;return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
对象在Hash表中存放的位置算法为=key.hashCode()&(length-1);
又由于Hash表初始长度为16,减去1为15
00000000 00000000 00000000 00001111与无论什么值取&结果都只能由后四位决定(0&1=0; 0&0=0; 1&0=0; 1&1=1;)
例如
00000000 00000000 00000000 00001111 16-1 (16hash表初始长度)
11000101 10011101 10000001 11110100 HashCode
00000000 00000000 00000000 00000100 结果
这样做的话hash冲突会很大所以采用一个办法,将hashCode右移16位与自己取^,产生的值作为新值去做运算
00000000 00000000 11000101 10011101 HashCode
11000101 10010101 10000001 11110100 h>>>16
11000101 10010101 01000100 01101001 新值 (更加散列)
用新值算对象在Hash表中存放的位置算法为=key.hashCode()&(length-1);
又由于Hash表初始长度为16,减去1为15
00000000 00000000 00000000 00001111
11000101 10010101 01000100 01101001
00000000 00000000 00000000 00001001
等于9
获得的值更加散列,减少Hash冲突
7.HashMap底层在·jdk1.8后的改动
当发现链表表中的链表长度大于8时,当发现链表中的元素个数大于8之后,
1.还会判断一下当前数组的长度,如果数组长度小于64时,此时并不会转化为红黑树,而是进行扩容。
2.只有当链表中的元素个数大于8,并且数组的长度大于等于64时才会将链表转为红黑树
HashMap究极详细相关推荐
- 冒泡排序法究极详细讲解*
冒泡排序法究极详细讲解* 前言:冒泡排序法是排序问题中最通解与基础的方法.它是利用循环结构对一连串的数字进行排序.接下来就和大家分享具体原理与食用方法. 文章目录 冒泡排序法究极详细讲解* 一.基本原 ...
- Hadoop安装教程_伪分布式配置-Ubuntu-CentOS6(究极详细、厦门大学数据库实验室)
Hadoop安装教程_伪分布式配置_CentOS6.4/Hadoop2.6.0 Hadoop安装教程_单机/伪分布式配置_Hadoop2.6.0(2.7.1)/Ubuntu14.04(16.04) 林 ...
- 【究极详细版】Ubuntu安装配置MySQL
安装 通过包管理工具apt安装,在ubuntu20.04下mysql版本默认为8.0,而ubuntu18.04在截至本文完成时默认版本为5.7.如果想在20.04下安装5.7版本,可以看这篇连接. 首 ...
- LaTeX半小时速成究极进化版(修改版)
唔~~~今年期末考得还凑合~~~今年寒假过得也还凑合(某只昂昂昂,你知道我zhai说你~~~)~~~又看到有人在转一些关于LaTeX的东东,觉得网上给的模板要不只适用于英文论文(维基百科上面对于一些数 ...
- html css奥义之血轮进化轮回究极无敌眼
这篇文章关键介绍了html css奥义之血轮进化轮回究极无敌眼 ,文中根据案例编码给大伙儿介绍的十分详尽,对大伙儿的学习培训或工作中具备一定的参考借鉴使用价值,必须的盆友能够参考下 效果(完整代码在底 ...
- 一篇HITSZ的究极情况_个人向
说明 本文完全是给自己做一个纪念,涉及的内容诸君自己参考 后续每个部分都会抽开来写 答辩完后走回宿舍的路上看到深圳冬日的阳光,不禁感慨自己的大学生涯(至少是考试生涯)就这样画上了句号.有很多想说的到了 ...
- Android的WebView控件载入网页显示速度慢的究极解决方案
Android的WebView控件载入网页显示速度慢的究极解决方案 [转载来源自http://hi.baidu.com/goldchocobo/] Android客户端中混搭HTML页面,会出现虽然H ...
- 极详细的ECC讲解 -OOB与ECC
http://blog.csdn.net/dongzhichen/article/details/8249228 详细的ECC讲解 -OOB与ECC 在网络编程中 OOB(out of band)带外 ...
- Qt总结:QMessageBox(原生态弹出框及究极超nice封装自定义弹出框)
一.前言 在Qt中经常需要弹出窗口,QMessageBox可以实现此功能,一共有三种窗口,information, question, 和 warning,critical, about分别对应感叹号 ...
最新文章
- 网络信息安全之防火墙的设计 (三)
- 结合自己造的轮子实践按需加载
- 常见的计算机系统结构不包括,计算机系统结构
- Django周总结一
- sublime的package control安装注意
- vue 方法获取返回值_Vue项目中Api的组织和返回数据处理的操作
- asp.net MD5数据加密和解密
- win7 mac虚拟机linux,Mac虚拟机parallels desktop超详细安装Win7图文分解
- python中series是什么_pandas中的series数据类型详解
- android零基础教程,Android零基础入门|Activity初入门,创建和配置如此简单
- 电脑运行c语言时错误,电脑出现microsoft visual c++ runtime error 解决方法(多图)
- JLink JTAG和SWD模式引脚定义
- 虚拟主机需要备案吗?
- gif动图怎么制作?怎么截取视频做成gif动图?
- Predicting Lymph Node Metastasis Using Histopathological Images Based on Multiple Instance Learning
- js和css压缩工具
- mysql定时任务每天凌晨三点钟醒来_linux cron 下的定时执行工具使用技巧
- 深度:从 Office 365 新图标来看微软背后的设计新理念
- 【SDCC讲师专访】全栈工匠老曹:如何去认识全栈架构师?
- Windows10精简优化无人值守安装