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究极详细相关推荐

  1. 冒泡排序法究极详细讲解*

    冒泡排序法究极详细讲解* 前言:冒泡排序法是排序问题中最通解与基础的方法.它是利用循环结构对一连串的数字进行排序.接下来就和大家分享具体原理与食用方法. 文章目录 冒泡排序法究极详细讲解* 一.基本原 ...

  2. Hadoop安装教程_伪分布式配置-Ubuntu-CentOS6(究极详细、厦门大学数据库实验室)

    Hadoop安装教程_伪分布式配置_CentOS6.4/Hadoop2.6.0 Hadoop安装教程_单机/伪分布式配置_Hadoop2.6.0(2.7.1)/Ubuntu14.04(16.04) 林 ...

  3. 【究极详细版】Ubuntu安装配置MySQL

    安装 通过包管理工具apt安装,在ubuntu20.04下mysql版本默认为8.0,而ubuntu18.04在截至本文完成时默认版本为5.7.如果想在20.04下安装5.7版本,可以看这篇连接. 首 ...

  4. LaTeX半小时速成究极进化版(修改版)

    唔~~~今年期末考得还凑合~~~今年寒假过得也还凑合(某只昂昂昂,你知道我zhai说你~~~)~~~又看到有人在转一些关于LaTeX的东东,觉得网上给的模板要不只适用于英文论文(维基百科上面对于一些数 ...

  5. html css奥义之血轮进化轮回究极无敌眼

    这篇文章关键介绍了html css奥义之血轮进化轮回究极无敌眼 ,文中根据案例编码给大伙儿介绍的十分详尽,对大伙儿的学习培训或工作中具备一定的参考借鉴使用价值,必须的盆友能够参考下 效果(完整代码在底 ...

  6. 一篇HITSZ的究极情况_个人向

    说明 本文完全是给自己做一个纪念,涉及的内容诸君自己参考 后续每个部分都会抽开来写 答辩完后走回宿舍的路上看到深圳冬日的阳光,不禁感慨自己的大学生涯(至少是考试生涯)就这样画上了句号.有很多想说的到了 ...

  7. Android的WebView控件载入网页显示速度慢的究极解决方案

    Android的WebView控件载入网页显示速度慢的究极解决方案 [转载来源自http://hi.baidu.com/goldchocobo/] Android客户端中混搭HTML页面,会出现虽然H ...

  8. 极详细的ECC讲解 -OOB与ECC

    http://blog.csdn.net/dongzhichen/article/details/8249228 详细的ECC讲解 -OOB与ECC 在网络编程中 OOB(out of band)带外 ...

  9. Qt总结:QMessageBox(原生态弹出框及究极超nice封装自定义弹出框)

    一.前言 在Qt中经常需要弹出窗口,QMessageBox可以实现此功能,一共有三种窗口,information, question, 和 warning,critical, about分别对应感叹号 ...

最新文章

  1. 网络信息安全之防火墙的设计 (三)
  2. 结合自己造的轮子实践按需加载
  3. 常见的计算机系统结构不包括,计算机系统结构
  4. Django周总结一
  5. sublime的package control安装注意
  6. vue 方法获取返回值_Vue项目中Api的组织和返回数据处理的操作
  7. asp.net MD5数据加密和解密
  8. win7 mac虚拟机linux,Mac虚拟机parallels desktop超详细安装Win7图文分解
  9. python中series是什么_pandas中的series数据类型详解
  10. android零基础教程,Android零基础入门|Activity初入门,创建和配置如此简单
  11. 电脑运行c语言时错误,电脑出现microsoft visual c++ runtime error 解决方法(多图)
  12. JLink JTAG和SWD模式引脚定义
  13. 虚拟主机需要备案吗?
  14. gif动图怎么制作?怎么截取视频做成gif动图?
  15. Predicting Lymph Node Metastasis Using Histopathological Images Based on Multiple Instance Learning
  16. js和css压缩工具
  17. mysql定时任务每天凌晨三点钟醒来_linux cron 下的定时执行工具使用技巧
  18. 深度:从 Office 365 新图标来看微软背后的设计新理念
  19. 【SDCC讲师专访】全栈工匠老曹:如何去认识全栈架构师?
  20. Windows10精简优化无人值守安装

热门文章

  1. 金融人士如何建立自己的人脉?
  2. 网站架构:负载均衡(下)
  3. Distance Tree 全网最丑做法
  4. 小虎电商浏览器:拼多多补货要多长时间最好?是否有影响?
  5. 班德尔服务器最新所在地,LOL:班德尔城被誉为四川区,班德尔城服务器在四川,延迟只有4...
  6. pr新建的字幕和老字幕保持一样的参数设置
  7. 51单片机可以接摄像头吗?
  8. 宏观经济学-案例大题
  9. pyecharts画桑基图,保存为html和png问题
  10. html ios返回后刷新页面,Ios中微信页面返回上一页去除缓存几种常见思路