【夯实Java基础】(五)轻松掌握 HashMap 源码

简介: 【夯实Java基础】(五)轻松掌握 HashMap 源码

文章目录


引子

图解 HashMap 的数据结构

详细分析 HashMap 源码的代码


引子


计算机中如果存储数据的话,我们该怎么办?

数据在计算机中存储的一个方式/结构(数据结构)

如果我们对 HashMap 底层的数据结构都搞清楚,那应该能有助于我们看懂源码。


数据结构?? 数组、链表、树形、图形


20191205144639112.png


图解 HashMap 的数据结构


Key,value---------------------> HashMap 的数据结构应该比较吊

我们可以大胆的猜测 HashMap 应该是将 数组和链表的优势结合起来

数组+链表的形式 -----------> HashMap 的数据结构 jdk1.8 红黑树


20191205150939986.png


紫色部分即代表哈希表本身(其实是一个数组),数组的每个元素都是一个单链表的头节点,链表是用来解决hash地址冲突的,如果不同的key映射到了数组的同一位置处,就将其放入单链表中保存。


详细分析 HashMap 源码的代码


数组的表示:Node table[]


20191205151753799.png


默认初始容量为16


20191205151941173.png


20191205152121843.png


数组的大小可能会不够用 扩大


问题是? 什么时候进行扩大? 数组16已经用到16的时候再扩大呗?


从感性层面和理性层面来看,我们可以看到 16*0.75=12 数组扩大的一个标准


Java是面向对象的,从上图的双向链表来看,我们可以猜测用代码实现双向链表大概如下:

class Node{
    Object data;
    Node prev;
    Node next;
  }


这在LinkedList源码中得到验证。


20191205145456794.png


链表的长度不能无限大,怎么叫做一个上限?

链表和红黑树之间的转变----------> 相对适合它们各自效率的一个节点


20191205153103285.png


20191205153223509.png


记录一下数组使用格子的数量


size=0 size++


20191205153454242.png


来了一个 key,value 组成了 Node 节点后, 这个节点到底该何去何从?


数组的大小 16

Random.next(16) 0-15

如果落点的算法仅仅是这样的话,就未免太low了

数组的 16 个位置要充分利用其中的 12 个


----------------------------->


生成出一个算法 hash 算法

(1) Int

Key,value -----------------------> key Object ------------------>key.hashCode()

32434535(一个哈希值) hash


(2) 0-15 数组的大小范围

Hash%16 0-15


(3) 尽可能充分利用数组的每一个位置


20191205164232671.png


到了这里,我对 Node 节点的属性都已了然于心。


继续看源码,数组先进行了初始化:

Node[] table = new Node[16];

Resize() 功能 是可以对数组进行初始化操作


20191205164755411.png


把数组的默认大小 和 16*0.75


20191205164936673.png


threshold = 12


20191205165059326.png


(1) 数组原本的位置为空

(2) 数组原本的位置不为空,且下面是链表结构


20191205184014869.png


(3) 数组原本的位置不为空,且下面是红黑树结构


20191205173701919.png


n-1{15} & hash <------------------------ > hash % n{16} 0-15


20191205183055274.png


Key.hashCode() 高16位和16位进行异或运算,这样结果才能尽可能不同


20191205183240834.png


20191205153454242 (1).png


Resize() 数组的初始化操作 数组的扩容的操作


20191205185226386.png


Double 2 倍 为什么是两倍进行扩大数组呢??


20191205190854523.png


16 ------> 32

12 ------> 24


20191205191515940.png


为什么下面还要有代码呢??


因为节点不要总是赖在原来的数组中,也要往新的数组中移动。(重新散列)


老数组进行判断,如果下面是空,进行重新hash 得到一个新的位置


20191205191757161.png


如果为0,保持在原来的位置不动

如果不为0,加上原来的capacity

Hash n-1


1.8 中实现了

TreeNode Parent left right

Treelfy_Threshold 8 超过了这个8 链表----红黑树

Put 判断链表的长度


目录
相关文章
|
18天前
|
Java
Java之HashMap详解
本文介绍了Java中HashMap的源码实现(基于JDK 1.8)。HashMap是基于哈希表的Map接口实现,允许空值和空键,不同步且线程不安全。文章详细解析了HashMap的数据结构、主要方法(如初始化、put、get、resize等)的实现,以及树化和反树化的机制。此外,还对比了JDK 7和JDK 8中HashMap的主要差异,并提供了使用HashMap时的一些注意事项。
Java之HashMap详解
|
7天前
|
数据采集 人工智能 Java
Java产科专科电子病历系统源码
产科专科电子病历系统,全结构化设计,实现产科专科电子病历与院内HIS、LIS、PACS信息系统、区域妇幼信息平台的三级互联互通,系统由门诊系统、住院系统、数据统计模块三部分组成,它管理了孕妇从怀孕开始到生产结束42天一系列医院保健服务信息。
22 4
|
13天前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
44 2
|
2月前
|
存储 Java
Java中的HashMap和TreeMap,通过具体示例展示了它们在处理复杂数据结构问题时的应用。
【10月更文挑战第19天】本文详细介绍了Java中的HashMap和TreeMap,通过具体示例展示了它们在处理复杂数据结构问题时的应用。HashMap以其高效的插入、查找和删除操作著称,而TreeMap则擅长于保持元素的自然排序或自定义排序,两者各具优势,适用于不同的开发场景。
44 1
|
2月前
|
存储 安全 Java
Java Map新玩法:探索HashMap和TreeMap的高级特性,让你的代码更强大!
【10月更文挑战第17天】Java Map新玩法:探索HashMap和TreeMap的高级特性,让你的代码更强大!
63 2
|
18天前
|
人工智能 监控 数据可视化
Java智慧工地信息管理平台源码 智慧工地信息化解决方案SaaS源码 支持二次开发
智慧工地系统是依托物联网、互联网、AI、可视化建立的大数据管理平台,是一种全新的管理模式,能够实现劳务管理、安全施工、绿色施工的智能化和互联网化。围绕施工现场管理的人、机、料、法、环五大维度,以及施工过程管理的进度、质量、安全三大体系为基础应用,实现全面高效的工程管理需求,满足工地多角色、多视角的有效监管,实现工程建设管理的降本增效,为监管平台提供数据支撑。
32 3
|
23天前
|
运维 自然语言处理 供应链
Java云HIS医院管理系统源码 病案管理、医保业务、门诊、住院、电子病历编辑器
通过门诊的申请,或者直接住院登记,通过”护士工作站“分配患者,完成后,进入医生患者列表,医生对应开具”长期医嘱“和”临时医嘱“,并在电子病历中,记录病情。病人出院时,停止长期医嘱,开具出院医嘱。进入出院审核,审核医嘱与住院通过后,病人结清缴费,完成出院。
59 3
|
28天前
|
JavaScript Java 项目管理
Java毕设学习 基于SpringBoot + Vue 的医院管理系统 持续给大家寻找Java毕设学习项目(附源码)
基于SpringBoot + Vue的医院管理系统,涵盖医院、患者、挂号、药物、检查、病床、排班管理和数据分析等功能。开发工具为IDEA和HBuilder X,环境需配置jdk8、Node.js14、MySQL8。文末提供源码下载链接。
|
2月前
|
存储 Java 程序员
Java面试加分点!一文读懂HashMap底层实现与扩容机制
本文详细解析了Java中经典的HashMap数据结构,包括其底层实现、扩容机制、put和查找过程、哈希函数以及JDK 1.7与1.8的差异。通过数组、链表和红黑树的组合,HashMap实现了高效的键值对存储与检索。文章还介绍了HashMap在不同版本中的优化,帮助读者更好地理解和应用这一重要工具。
55 5
|
2月前
|
移动开发 前端开发 JavaScript
java家政系统成品源码的关键特点和技术应用
家政系统成品源码是已开发完成的家政服务管理软件,支持用户注册、登录、管理个人资料,家政人员信息管理,服务项目分类,订单与预约管理,支付集成,评价与反馈,地图定位等功能。适用于各种规模的家政服务公司,采用uniapp、SpringBoot、MySQL等技术栈,确保高效管理和优质用户体验。