HashMap源码分析

2023-11-15

目录

hashmap1.8源码大纲

那么问题来了?

hashmap的数据结构?

为什么扩容长度必须是2的指数次幂也就是2的n次方?

为什么加载因子是0.75?

为什么数组转链表阈值是8?

key能否为空?

hashmap为什么线程不安全?


hashmap1.8源码大纲

1 HashMap继承与AbstratMap实现了Map、cloneable、serilizable接口。

2 首先有一个静态长整型serialVersionUID。

3 然后是一些常量的定义比如默认初始容量16,最大容量2的30次方,浮点数默认加载因子0.75,链表转树树阈值8,树转链表阈值6,最小转成树的map容量为64。

4 然后是 节点类node继承与Map的Entry,Node类有四个成员变量 hash,key,value,next,构造方法还有getKey,getValue,toString,hashCode,setvalue,equals方法。

5 然后是静态公用工具方法,比如hash(Object),comparableClassFor(Object),compareComparables(),tableSizeFor(),

6 然后是一些成员变量,Node数组table,Entry Set entrySet,size,modCount,int threshold,浮点数loadfactor, 

7 然后是一些公共的操作,HashMap的四个构造函数,putMapEntries(),size(),isEmpty(),get(),getNode(),containsKey(),put(),putVal(),resize(),treeifyBin(),putAll(),remove(),removeNode(),clear(),containsValue(),keySet(),类KeySet,values,类Values,entrySet(),类EntrySet,

8 然后是一些覆盖的方法,比如getOrDefault(),putIfAbsent(),remove(),replace(),replace(),compareIfAbsent(),compareIfAbsent(),compute(),merge(),forEach(),replaceAll(),clone(),

9 然后是一些其他的方法loadFactor(),capacity(),writeObject(),readObjet(),

10 然后是迭代器相关,抽象类HashIterator,类keyItetator,valueIterator,EntryIterator,

11 然后是分离器相关,HashMapSpliterator,keySpliterator,ValueSpliterator,EntrySpliterator,

12 然后是链表支持,newNode(),replacementNode(),newTreeNode(),replacementTreeNode(),reinitialize(),afterNodeAccess(),afterNodeInsertion(),afterNodeRemoval()

13 最后是TreeNode类,继承于LinkedHashMap.Entry

那么问题来了?

hashmap的数据结构?

数组  链表 红黑树(java>1.7)

为什么用数组?数组索引下标存取快,O(1),查找的时候也要遍历链表,

红黑树对链表性能做了优化,接近于平衡二叉树,

查找插入删除

 

为什么扩容长度必须是2的指数次幂也就是2的n次方?

因为hash运算之后存储在数组的那个位置是有hash值对数组长度取模计算完成。

1取模运算的效率低于位运算

2必须是2的n次方取模和位运算才能划等号,h&length-1 == h%length

3Java8以下会rehash,rehash将会非常消耗性能

为什么加载因子是0.75?

牛顿二项式 时间空间的平衡 .net是0.72

为什么数组转链表阈值是8?

泊松分布 8的概念非常小亿分之六,而且链表为8但是数组长度不满64也不会转红黑树。链表为8其实意味着当前链表长度为9,因为是算的表头以外长度为8.

key能否为空?

可以为空,HashMap最多只允许一条记录的键为null,允许多条记录的值为null(hashtable是不允许的,会报异常)。

static final int hash(Object key) {
        int h;
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    } //来自hashmap源码
 HashMap mHashMap = new HashMap();
        mHashMap.put(null, "11");
        mHashMap.put(null, 11);
        mHashMap.put(null, 11.9f);
        System.out.println(mHashMap.size()); //打印的值为1
 HashMap mHashMap = new HashMap();
        mHashMap.put(1, null);
        mHashMap.put(2, null);
        mHashMap.put(3, null);
        System.out.println(mHashMap.size());//打印的值为3

hashmap为什么线程不安全?

因为扩容死锁会形成链表死环。

10个线程,每个线程put100万次

为什么会形成链表死环?

扩容,链表调换顺序,第二个线程就会杨过和小龙女互相指向,形成链表死环。

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

HashMap源码分析 的相关文章

  • 存根方法时出现 InvalidUseOfMatchersException

    我有这个 TestNG 测试方法代码 InjectMocks private FilmeService filmeService new FilmeServiceImpl Mock private FilmeDAO filmeDao Bef
  • Java Runtime.getRuntime().freeMemory() 问题

    我搜索并看到了一些线程 但没有一个能够解决我遇到的具体问题 我正在尝试使用以下方式监视我的内存使用情况Runtime getRuntime freeMemory Runtime getRuntime maxMemory and Runtim
  • 通过SOCKS代理连接Kafka

    我有一个在 AWS 上运行的 Kafka 集群 我想用标准连接到集群卡夫卡控制台消费者从我的应用程序服务器 应用程序服务器可以通过 SOCKS 代理访问互联网 无需身份验证 如何告诉 Kafka 客户端通过代理进行连接 我尝试了很多事情 包
  • 使用 Ant 将非代码资源添加到 jar 文件

    我正在将 java 应用程序打包成 jar 文件 我正在使用 ant 和 eclipse 我实际上需要在 jar 中直接在根文件夹下包含几个单独的非代码文件 xml 和 txt 文件 而不是与代码位于同一位置 我正在尝试使用includes
  • 使用 GWT 读取非常大的本地 XML 文件

    我正在使用 GWT 构建我的第一个 Java 应用程序 它必须从一个非常大的 XML 文件中读取数据 当我尝试发送对文件中信息的请求时遇到问题 并且我不太确定它是否与文件的大小或我的语义有关 在我的程序中 我有以下内容 static fin
  • 在 Wildfly 中与 war 部署共享 util jar 文件

    假设我有一个名为 util jar 的 jar 文件 该 jar 文件主要包含 JPA 实体和一些 util 类 无 EJB 如何使这个 jar 可用于 Wildfly 中部署的所有 war 无需将 jar 放置在 war 的 WEB IN
  • Spring Security SAML2 使用 G Suite 作为 Idp

    我正在尝试使用 Spring Security 5 3 3 RELEASE 来处理 Spring Boot 应用程序中的 SAML2 身份验证 Spring Boot 应用程序将成为 SP G Suite 将成为 IDP 在我的 Maven
  • ConcurrentHashMap 内部是如何工作的?

    我正在阅读有关 Java 并发性的 Oracle 官方文档 我想知道Collection由返回 public static
  • 自动生成Flyway的迁移SQL

    当通过 Java 代码添加新模型 字段等时 JPA Hibernate 的自动模式生成是否可以生成新的 Flyway 迁移 捕获自动生成的 SQL 并将其直接保存到新的 Flyway 迁移中 以供审查 编辑 提交到项目存储库 这将很有用 预
  • 生成的序列以 1 开头,而不是注释中设置的 1000

    我想请求一些有关 Hibernate 创建的数据库序列的帮助 我有这个注释 下面的代码 在我的实体类中 以便为合作伙伴表提供单独的序列 我希望序列以 1000 开头 因为我在部署期间使用 import sql 将测试数据插入数据库 并且我希
  • 如何避免 ArrayIndexOutOfBoundsException 或 IndexOutOfBoundsException? [复制]

    这个问题在这里已经有答案了 如果你的问题是我得到了java lang ArrayIndexOutOfBoundsException在我的代码中 我不明白为什么会发生这种情况 这意味着什么以及如何避免它 这应该是最全面的典范 https me
  • 使用 Mockito 模拟某些方法,但不模拟其他方法

    有没有办法使用 Mockito 模拟类中的某些方法 而不模拟其他方法 例如 在这个 诚然是人为的 Stock我想嘲笑的班级getPrice and getQuantity 返回值 如下面的测试片段所示 但我想要getValue 执行乘法 如
  • Freemarker 和 Struts 2,有时它计算为序列+扩展哈希

    首先我要说的是 使用 Struts2 Freemarker 真是太棒了 然而有些事情让我发疯 因为我不明白为什么会发生这种情况 我在这里问是因为也许其他人有一个想法可以分享 我有一个动作 有一个属性 说 private String myT
  • HashMap 值需要不可变吗?

    我知道 HashMap 中的键需要是不可变的 或者至少确保它们的哈希码 hashCode 不会改变或与另一个具有不同状态的对象发生冲突 但是 HashMap中存储的值是否需要与上面相同 为什么或者为什么不 这个想法是能够改变值 例如在其上调
  • Docker 和 Eureka 与 Spring Boot 无法注册客户端

    我有一个使用 Spring Boot Docker Compose Eureka 的非常简单的演示 我的服务器在端口 8671 上运行 具有以下应用程序属性 server port 8761 eureka instance prefer i
  • java库维护数据库结构

    我的应用程序一直在开发 所以偶尔 当版本升级时 需要创建 更改 删除一些表 修改一些数据等 通常需要执行一些sql代码 是否有一个 Java 库可用于使我的数据库结构保持最新 通过分析类似 db structure version 信息并执
  • 返回 Java 8 中的通用函数接口

    我想写一种函数工厂 它应该是一个函数 以不同的策略作为参数调用一次 它应该返回一个函数 该函数根据参数选择其中一种策略 该参数将由谓词实现 嗯 最好看看condition3为了更好的理解 问题是 它没有编译 我认为因为编译器无法弄清楚函数式
  • 在浏览器刷新中刷新检票面板

    我正在开发一个付费角色系统 一旦用户刷新浏览器 我就需要刷新该页面中可用的统计信息 统计信息应该从数据库中获取并显示 但现在它不能正常工作 因为在页面刷新中 java代码不会被调用 而是使用以前的数据加载缓存的页面 我尝试添加以下代码来修复
  • Java EE 目录结构

    我对以下教程有疑问 http www mkyong com jsf2 jsf 2 internationalization example http www mkyong com jsf2 jsf 2 internationalizatio
  • 在java中使用多个bufferedImage

    我正在 java 小程序中制作游戏 并且正在尝试优化我的代码以减少闪烁 我已经实现了双缓冲 因此我尝试使用另一个 BufferedImage 来存储不改变的游戏背景元素的图片 这是我的代码的相关部分 public class QuizApp

随机推荐

  • SAP 科目的 未清项管理的理解

    清账的事务代码 自动清账 F 13 总账清账 F 04 供应商清账 F 53 客户清账 F032 未清项管理是SAP的一个重要功能 通过未清项管理可以实现付款 收款 的一一对应 以及准确的账龄分析 会计科目设置此标志后 系统会将凭证行标记为
  • 在虚拟磁盘中安装Windows Server 2016

    说起来我一直没有安装过Windows服务器版的系统 所以最近想尝试一下Windows Server 2016 这个最新的Windows服务器系统 当然如果是家用的话 肯定还是安装桌面版的系统更好 服务器版的系统主要是企业使用 日常功能反而不
  • python读取每一行再按照空格分隔

    all with open number txt r as f for line in f readlines curLine line strip split print curLine all append curLine f clos
  • 附近商家位置java开发附近定位

    根据给定经纬度 lat lng 求出其左上角 left top 右上角 right top 左下角 left bottom 右下角 right bottom 的四个位置 所有在这个区域的范围都在该点附近 public class Test
  • 最新计算机毕业设计选题推荐 - 毕设选题建议

    文章目录 0 前言 1 java web 管理系统 毕设选题 2 java web 平台 业务系统 毕设选题 3 游戏设计 动画设计类 毕设选题 适合数媒的同学 4 算法开发 5 数据挖掘 毕设选题 6 大数据处理 云计算 区块链 毕设选题
  • 2020全国网络安全知识竞赛链工宝答案 爬取 自动答题

    要用浏览器打开公众号的练题库 然后就可以自动获取答案 最下面是我获取到的300多个题 差不多就这些了 可以进一个加个函数自动答题 def fu try browser refresh time sleep 2 xx browser find
  • STM32F103RET6 ADC配置流程

    STM32F103RET6 ADC基本配置流程 首先 使用RCC库函数RCC APB2PeriphClockCmd使能ADC时钟 可以使用以下代码 RCC APB2PeriphClockCmd RCC APB2Periph ADC1 ENA
  • 开环控制系统与闭环控制系统

    开环控制系统是指无被控量反馈的控制系统 即需要控制的是被控对象的某一量 被控量 而测量的只是给定信号 被控量对于控制作用没有任何影响的系统 结构如图所示 闭环控制的定义是有被控制量反馈的控制 其原理框如图所示 从系统中信号流向看 系统的输出
  • 最强Transformer发布!谷歌大脑提出ViT-G:缩放视觉Transformer,高达90.45%准确率!

    Scaling Vision Transformers 论文 https arxiv org abs 2106 04560 1简介 视觉Transformer ViT 等基于注意力的神经网络最近在许多计算机视觉基准测试中取得了最先进的结果
  • 关于在uni-app中引入组件、css样式以及js文件的方法总结

    uni app是使用vue js开发多端应用的框架 可以说为一些钱多开发者提供了很大的方便 近些天学习了一下vue js 可当开始开发的时候却不知怎么去将文件分块 然后查了一下 发现引入文件确实与传统的html不一样 总结了一下分别引入组件
  • TM1638芯片 LED数码管驱动器 详细介绍

    相比MAX7219 TM1638的操作更加复杂 但是功能也更加强大 目录 TM1638简介 器件特性 TM1638引脚图 引脚功能说明 TM1638地址组 显存地址 键值地址 TM1638指令表 指令分类 数据命令 地址命令 显示控制命令
  • 多个前端项目部署在nginx中同一个server下

    多个前端项目部署在同一个域名下 在vue config js中设置 publicPath web 在路由index js中设置 base web 在index html中加入 修改NGINX设置 基本就是使location 指向原来的web
  • 日本传统色彩大全

    古代紫 895b8a 茄子紺 824880 二藍 915c8b 京紫 9d5b8b 蒲葡 7a4171 若紫 bc64a4 紅紫 b44c97 梅紫 aa4c8f 菖蒲色 cc7eb1 紅藤色 cca6bf 浅紫 c4a3bf 紫水晶 e7
  • 同时配置cuda11.0和11.1环境

    同时配置cuda11 0和11 1环境 背景 思路 流程 电脑环境确认 确认位置 安装新CUDA环境 1 执行cuda exe 2 配置环境变量 安装cudnn 背景 在电脑上安装多个版本的cuda 电脑已经安装好了cuda11 0 由于m
  • 青蛙跳台阶(java)

    一 问题描述 一只青蛙一次可以跳上1级台阶 也可以跳上2级 求该青蛙跳上一个n级的台阶总共有多少种跳法 二 算法分析 因为青蛙一次只能跳上1级台阶或者两级台阶 所以对于第n级台阶来说 青蛙只能从第n 1级台阶或者第n 2级台阶跳上 设青蛙跳
  • dnSpy反编译、部署调试记录

    一 概要 在工作当中 当程序部署了之后就算打了日志遇到极个别的特殊异常没有在程序日志中体现出来或者没有详细的报错原因会让开发者非常头疼 不得不盲猜bug到底出在哪里 这里分享一下工作上经常会用到的工具 这款工具可以反编译并运行调试已经部署好
  • 2023蓝桥杯 试题E:接龙数列

    include
  • PCB设计基础概念

    芯片电源 VCC 即接入电路的电压 VDD 即器件内部的工作电压 VSS 即电路公共接地端电压 GND 即电压参考基点 VEE 负电压供电 VPP 编程 擦除电压 V 与 V A的区别是 数字与模拟的区别 型滤波设计 晶体电路设计多采用 型
  • 国产开源大模型: 百亿参数“伶荔”,填补中文基础模型空白!

    Datawhale开源 团队 深圳大学沈琳琳教授团队 Linly 伶荔说 中文语言大模型来啦 大数据系统计算技术国家工程实验室副主任 深圳大学计算机与软件学院沈琳琳教授团队主持的人工智能项目 伶荔 Linly 于今天隆重推出 伶荔说 系列中
  • HashMap源码分析

    目录 hashmap1 8源码大纲 那么问题来了 hashmap的数据结构 为什么扩容长度必须是2的指数次幂也就是2的n次方 为什么加载因子是0 75 为什么数组转链表阈值是8 key能否为空 hashmap为什么线程不安全 hashmap