当前位置: 首页 > news >正文

Java HashMap源码学习

Java HashMap源码学习

基本使用

包含创建,添加,删除,迭代,打印

val map = java.util.HashMap<Int, Int>()
map.put(1, 2)
map.put(2, 2)
map.put(3, 2)
map.remove(1)
map.forEach {println("it.key=${it.key}, it.value=${it.value}")
}
println(map)

分析源码

一贯原则,没用的帮兄弟们省掉了

简单介绍

package java.util;// AbstractMap,可以随机访问
public class HashMap<K, V> extends AbstractMap<K, V> {// 初始容量static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // 最大容量static final int MAXIMUM_CAPACITY = 1 << 30;// 负载因子,当前容量超过最大容量*负载因子,开始扩容static final float DEFAULT_LOAD_FACTOR = 0.75f;// 链表大于8树化static final int TREEIFY_THRESHOLD = 8;// 树小于6链化static final int UNTREEIFY_THRESHOLD = 6;// 树化的最小容量static final int MIN_TREEIFY_CAPACITY = 64;// 存储key,valuestatic class Node<K, V> implements Map.Entry<K, V> {// 通过key中字段计算final int hash;final K key;V value;Node<K, V> next;Node(int hash, K key, V value, Node<K, V> next) {this.hash = hash;this.key = key;this.value = value;this.next = next;}// 省略get,set等模板方法}
}

创建

// 负载因子
public HashMap() {this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted
}

添加

public V put(K key, V value) {// 通过hash()对key进行一次hash()return putVal(hash(key), key, value);
}// 重点分析
final V putVal(int hash, K key, V value) {// tab,桶,就是数组// p,期望对象// n,当前桶容量// i,桶下标Node<K,V>[] tab; Node<K,V> p; int n, i;// 如果是第一次,通过resize()更新初始容量if ((tab = table) == null || (n = tab.length) == 0)n = (tab = resize()).length;// 与桶大小&计算,二次hash()// 刚好桶上没元素,直接在桶上更新if ((p = tab[i = (n - 1) & hash]) == null)tab[i] = newNode(hash, key, value, null);else {// e,辅助期望元素// k,桶下标元素的keyNode<K,V> e; K k;// 如果和桶第一个一样if (p.hash == hash && ((k = p.key) == key || (key != null && key.equals(k))))e = p;// 已经树化的计算else if (p instanceof TreeNode)e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);// 链化的计算else {for (int binCount = 0; ; ++binCount) {// 没有相同的,在最后添加if ((e = p.next) == null) {p.next = newNode(hash, key, value, null);// 树化 if (binCount >= TREEIFY_THRESHOLD - 1)treeifyBin(tab, hash);break;}// 找到key一样的if (e.hash == hash &&((k = e.key) == key || (key != null && key.equals(k))))break;p = e;}}e.value = value;}// 扩容if (++size > threshold)resize();return null;
}// key经过hashCode()与低位^,让高位也参与计算
static final int hash(Object key) {int h;return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}// 二倍扩容
final Node<K,V>[] resize() {Node<K,V>[] oldTab = table;// 当前容量int oldCap = (oldTab == null) ? 0 : oldTab.length;// 当前负载int oldThr = threshold;int newCap, newThr = 0;if (oldCap > 0) {if (oldCap >= MAXIMUM_CAPACITY) {threshold = Integer.MAX_VALUE;return oldTab;}// 二倍扩容else if ((newCap = oldCap << 1) < MAXIMUM_CAPACITY &&oldCap >= DEFAULT_INITIAL_CAPACITY)newThr = oldThr << 1; // double threshold}else if (oldThr > 0) // initial capacity was placed in thresholdnewCap = oldThr;// 第一次扩容else {               // zero initial threshold signifies using defaultsnewCap = DEFAULT_INITIAL_CAPACITY;newThr = (int)(DEFAULT_LOAD_FACTOR * DEFAULT_INITIAL_CAPACITY);}if (newThr == 0) {float ft = (float)newCap * loadFactor;newThr = (newCap < MAXIMUM_CAPACITY && ft < (float)MAXIMUM_CAPACITY ?(int)ft : Integer.MAX_VALUE);}threshold = newThr;@SuppressWarnings({"rawtypes","unchecked"})// 大小确定,正式开始Node<K,V>[] newTab = (Node<K,V>[])new Node[newCap];table = newTab;if (oldTab != null) {// 遍历桶for (int j = 0; j < oldCap; ++j) {Node<K,V> e;if ((e = oldTab[j]) != null) {oldTab[j] = null;if (e.next == null)// 通过hash&新桶容量,计算位置newTab[e.hash & (newCap - 1)] = e;// 树转移else if (e instanceof TreeNode)((TreeNode<K,V>)e).split(this, newTab, j, oldCap);// 链表else { // preserve order// lo,low,hi,high,high=桶容量/2+lowNode<K,V> loHead = null, loTail = null;Node<K,V> hiHead = null, hiTail = null;Node<K,V> next;do {next = e.next;// 如果在下标0位置if ((e.hash & oldCap) == 0) {if (loTail == null)loHead = e;elseloTail.next = e;loTail = e;}else {if (hiTail == null)hiHead = e;elsehiTail.next = e;hiTail = e;}} while ((e = next) != null);if (loTail != null) {loTail.next = null;newTab[j] = loHead;}if (hiTail != null) {hiTail.next = null;newTab[j + oldCap] = hiHead;}}}}}return newTab;
}

总结

  1. HashMap可以存储键值对
  2. 初始容量是16,每次扩容2倍数
  3. 先添加,后扩容
  4. 从尾部添加

后续

里面代码确实挺多,其中还包括树,以后分析并尝试重写

相关文章:

Java HashMap源码学习

Java HashMap源码学习 基本使用 包含创建&#xff0c;添加&#xff0c;删除&#xff0c;迭代&#xff0c;打印 val map java.util.HashMap<Int, Int>() map.put(1, 2) map.put(2, 2) map.put(3, 2) map.remove(1) map.forEach {println("it.key${it.key}, it.va…...

Gin中用于追踪用户的状态的方法?!!!

Gin中的Cookie和Session的用法 文章目录 Gin中的Cookie和Session的用法介绍Cookie代码演示 Session代码展示 介绍 cookie 和 session 是 Web 开发中常用的两种技术&#xff0c;主要用于跟踪用户的状态信息。 Cookie func (c *Context) Cookie(name string, value string, max…...

HTTP代理与HTTPS代理在工作流程上有哪些区别

HTTP代理和HTTPS代理都是常见的代理技术&#xff0c;可以实现隐藏客户端IP地址、突破网络封锁、加速网站访问、过滤网络内容等功能。本文将介绍HTTP代理和HTTPS代理在工作流程上的区别。 HTTP代理的工作流程 客户端向代理服务器发送HTTP请求 当客户端需要访问某个网站时&#x…...

Docker从认识到实践再到底层原理(二-2)|Namespace+cgroups

前言 那么这里博主先安利一些干货满满的专栏了&#xff01; 首先是博主的高质量博客的汇总&#xff0c;这个专栏里面的博客&#xff0c;都是博主最最用心写的一部分&#xff0c;干货满满&#xff0c;希望对大家有帮助。 高质量博客汇总 然后就是博主最近最花时间的一个专栏…...

算法的概述

算法分析&#xff1a; 解决同一问题的算法可以有多种。 我们希望从中选出最优的算法&#xff0c;效率高或者存储空间小。为此&#xff0c;需要对算法进行评估&#xff0c;分析。 通常考虑两个度量&#xff1a; 1、 时间复杂度&#xff1a;算法运行时需要的总步数&#xff0c…...

菜鸟教程《Python 3 教程》笔记(19):错误与异常

菜鸟教程《Python 3 教程》笔记&#xff08;19&#xff09; 19 错误和异常19.1 assert&#xff08;断言&#xff09;19.2 异常处理19.2.1 try/except19.2.2 try/except...else19.2.3 try-finally 语句 19.3 抛出异常19.4 用户自定义异常19.5 清理行为19.5.1 定义清理行为19.5.2…...

空气净化器上亚马逊美国站需要办理什么认证?空气净化器UL867测试报告如何办理?

空气净化器又称“空气清洁器”、空气清新机、净化器&#xff0c;是指能够吸附、分解或转化各种空气污染物&#xff08;一般包括PM2.5、粉尘、花粉、异味、甲醛之类的装修污染、细菌、过敏原等&#xff09;&#xff0c;有效提高空气清洁度的产品&#xff0c;主要分为家用 、商用…...

SpringBoot的测试方案

写完代码后&#xff0c;测试是必不可少的步骤&#xff0c;现在来介绍一下基于SpringBoot的测试方法。 基于SpringBoot框架写完相应功能的Controller之后&#xff0c;然后就可以测试功能是否正常&#xff0c;本博客列举MockMvc和RestTemplate两种方式来测试。 准备代码 实体类…...

华为OD机考算法题:字符串解密

目录 题目部分 解读与分析 代码实现 题目部分 题目字符串解密题目说明给定两个字符串string1和string2。 string1是一个被加扰的字符串。string1由小写英文字母&#xff08;a~z&#xff09;和数字字符&#xff08;0~9&#xff09;组成&#xff0c;而加扰字符串由0~9、a~f 组…...

unity 锚点设置

锚点聚合情况&#xff1a; 一个2d物体的位置 pos x pos y 是中心点相对于锚点的偏移量&#xff1a; 中心点就是位置。 按住shift 锚点和中心点都会被设置&#xff1a; 按住Alt&#xff1a; 同时按住shift和alt &#xff1a; 中心点 锚点 UI元素在对应的位置上。 锚点拉伸情况…...

Hadoop:HDFS--分布式文件存储系统

目录 HDFS的基础架构 VMware虚拟机部署HDFS集群 HDFS集群启停命令 HDFS Shell操作 hadoop 命令体系&#xff1a; 创建文件夹 -mkdir 查看目录内容 -ls 上传文件到hdfs -put 查看HDFS文件内容 -cat 下载HDFS文件 -get 复制HDFS文件 -cp 追加数据到HDFS文件中 -appendTo…...

自定义封装异步任务组件,实现FutureTask功能

FutureTask 在 JDK1.8 后的异步编排API中的CompletableFuture&#xff0c;提供了 异步任务的成功回调、异常回调。 public class FutureTaskTest {public static void main(String[] args) throws Exception {CompletableFuture<String> future CompletableFuture.sup…...

【区块链 | IPFS】IPFS节点搭建、文件上传、节点存储空间设置、节点上传文件chunk设置

一、创建ipfs节点 通过ipfs init在本地计算机建立一个IPFS节点 本文有些命令已经执行过了&#xff0c;就没有重新初始化。部分图片拷贝自先前文档&#xff0c;具体信息应以实物为准 ipfs init initializing IPFS node at /Users/CHY/.ipfs generating 2048-bit RSA keypair.…...

【autodesk】浏览器中渲染rvt模型

使用Forge完成渲染 Forge是什么 为什么能够渲染出来rvt模型 Forge是由Autodesk开发的一套云端开发平台和工具集。在Forge平台中&#xff0c;有一个名为"Model Derivative"的服务&#xff0c;它可以将包括RVT&#xff08;Revit&#xff09;在内的多种BIM&#xff08…...

Python超入门(1)__迅速上手操作掌握Python

# 1.第一个代码&#xff1a;输出语句 # 1.第一个代码&#xff1a;输出语句 print("My dogs name is Huppy!") print(o----) print( ||| ) print("*" * 10) """ 输出结果&#xff1a; My dogs name is Huppy! o----||| ********** "&…...

后端面试话术集锦第 十四 篇:go语言面试话术

这是后端面试集锦第十四篇博文——go语言面试话术❗❗❗ 1. go数组、切片、扩容 go的数组和切片都是用来存储相同类型的数据集合。 数组是存储固定大小的集合,且为值引用。 但切片是存储无固定大小的集合,且为引用类型。 切片有三个属性,分别为指向指针的数组array,数组…...

Oralce集群管理-19C RAC 私有网络调整为BOND1

1 尝试在线添加私有网络的新接口 是否成功。 使用oifcfg命令在线添加新的网卡接口&#xff0c;在还没有配置bond1的条件下 也是可以添加成功的。 [gridorcldb1 ~]$ oifcfg getif eno3 192.168.224.0 global public ens3f0 10.2.0.0 global cluster_interconnect,asm eno…...

洛谷 Array 数论

题目&#xff1a; 对于长度为n的数组A&#xff0c;A中只包含从1到n的整数&#xff08;可重复&#xff09;。如果A单调不上升或单调不下降&#xff0c;A就可称为美丽的。 找出在长度为n时&#xff0c;有几个美丽的A。 思路&#xff1a; 这是一道数论题。 我们先找找“单调不递…...

简明SQL条件查询指南:掌握WHERE实现数据筛选

条件查询是用于从数据库中根据特定条件筛选数据行的一种方式&#xff0c;它避免了检索整个表中的数据。通常&#xff0c;使用 WHERE 子句来定义过滤条件&#xff0c;只有符合这些条件的数据行才会被返回。 SQL中的运算符有&#xff1a;、!、<、> 等&#xff0c;用于进行…...

通过HbaseClient来写Phoenix表实现

由于数据存储在Hbase上&#xff0c;并且上层使用了Phoenix来读写数据。并且由于数据的列字段不固定&#xff0c;并且可能由于Hbase表列和Phoenix的表列字段不一致&#xff0c;使用Phoenix写入的数据会导致写出报错的问题出现。所以这里直接使用HbaseClient写入到Hbase表中&…...

uniapp qiun charts H5使用echarts的eopts配置不生效

原因是&#xff1a;使用web的要设置 echartsH5 :echartsH5"true" <template><view class"charts-box"><view class"chart-title"> 趋势</view><qiun-data-chartstype"column":eopts"eopts":cha…...

嵌入式Linux驱动开发(LCD屏幕专题)(三)

1. 硬件相关的操作 LCD驱动程序的核心就是&#xff1a; 分配fb_info设置fb_info注册fb_info硬件相关的设置 硬件相关的设置又可以分为3部分&#xff1a; 引脚设置时钟设置LCD控制器设置 2. 在设备树里指定LCD参数 framebuffer-mylcd {compatible "100ask,lcd_drv&qu…...

MySQL视图用户管理

文章目录 视图视图的规则用户用户信息创建用户删除用户修改密码 用户权限给用户授权回收权限 视图 视图是一个虚拟表&#xff0c;其内容由查询定义。同真实的表一样&#xff0c;视图包含一系列带有名称的列和行数据。视图的数据变化会影响到基表&#xff0c;基表的数据变化也会…...

我发现了一个很好看的字体,霞鹜文楷!如何换windows和typora字体?

1、字体 官方地址如下&#xff0c;下载也很简单。 https://github.com/lxgw/LxgwWenKai 有1W多的stars。 方式&#xff1a; 直接打包下载。下载不来&#xff0c;可以联系我。 然后ttf的文件&#xff0c;全部安装就行了。 reg save "HKCU\Control Panel" .\res…...

微软8月系统更新引发问题:虚拟内存分页文件出现错误

微软的八月系统更新引发了一系列问题&#xff0c;其中包括“UNSUPPORTED_PROCESSOR”蓝屏错误和文件管理器故障。尽管微软已经修复了前者&#xff0c;但据国外科技媒体Windows Latest报道&#xff0c;仍有用户反馈在非微星设备上出现“fault in nonpaged area”蓝屏错误。 如果…...

swiper删除虚拟slide问题

在存在缓存的情况下&#xff0c;删除较前的slide&#xff0c;会出现当前slide与后一个slide重复出现的情况 假设当前存在5个slide&#xff0c;且这5个slide已缓存&#xff0c;则删除slide2后&#xff0c;仍为5个slide&#xff0c;且slide2的内容变为slide3的内容&#xff0c;此…...

FPGA实战小项目2

基于FPGA的贪吃蛇游戏 基于FPGA的贪吃蛇游戏 基于fpga的数字密码锁ego1 基于fpga的数字密码锁ego1 基于fpga的数字时钟 basys3 基于fpga的数字时钟 basys3...

一些关于完整小程序项目的优秀开源

转载自&#xff1a; 35个项目&#xff0c;开源&#xff0c;开源&#xff01; (qq.com) 那几本霸占我休息时间的PDF&#xff01; (qq.com) 13个超强的 SpringBoot 实战项目 &#xff08;还不赶紧收藏起来&#xff09; (qq.com) 用SpringBoot开发一个人脸识别系统&#xff01…...

Windows模拟器推荐

物是人非事事休&#xff0c;欲语泪先流 Windows模拟器推荐 如果你需要在 Windows 操作系统之外运行 Windows 应用程序或测试不同版本的 Windows&#xff0c;有几个 Windows 模拟器和虚拟机软件可供选择。以下是一些常用的 Windows 模拟器和虚拟机软件&#xff1a; VirtualBox&…...

搭建RabbitMQ消息服务,整合SpringBoot实现收发消息

作者主页&#xff1a;Designer 小郑 作者简介&#xff1a;3年JAVA全栈开发经验&#xff0c;专注JAVA技术、系统定制、远程指导&#xff0c;致力于企业数字化转型&#xff0c;CSDN博客专家&#xff0c;蓝桥云课认证讲师。 目录 一、前言1.1 什么是消息队列1.2 RabbitMQ 是什么1.…...

明薇通网站建设哪家好/东莞百度seo电话

目录 0. 相关文章链接 1. Flink中的累加器概述 2. 编码步骤 3. 代码演示 0. 相关文章链接 Flink文章汇总 1. Flink中的累加器概述 Flink中的累加器&#xff0c;与Mapreduce counter的应用场景类似&#xff0c;可以很好地观察task在运行期间的数据变化&#xff0c;如在Fli…...

贵阳论坛网站建设/竞价账户托管公司哪家好

面向对象:类 class 和 对象 object: 01. 什么是对象: 对象是指现实中的物体或实例 02. 什么是面向对象: 把一切看成对象&#xff08;实例),对象和对象之间用方法&#xff08;行为&#xff09;建立关联关系 面向过程是一件事怎么去一步一步实现, 面向对象是一件事有谁(实例)去实…...

建设导航网站费用/网页设计html代码大全

Perl命令行应用介绍Perl语言中有很多Perl命令行参数.通过它们,我们有机会写出更简单的程序&#xff0c;在这篇文章里我们来了解一些常用的参数。第一部分&#xff1a;SafetyNetOptions安全网参数在使用Perl尝试一些聪明(或stupid)的想法时,错误难免会发生.有经验的Perl程序员常…...

从零开始做一个网站需要多少钱/最新疫情新闻100字

计算轮廓点的最小凸包像素面积&#xff0c;最小外接圆的快速方法 计算轮廓点的最小凸包像素面积和求解最小外接圆的方法有很多&#xff0c;本文各举出一种比较简单且快速的方法&#xff0c;读者可根据实际情况定义返回值精度&#xff0c;本文采用的是整型精度&#xff0c;代码…...

网站备案关闭/新手怎么做网络销售

“没有缘创派&#xff0c;可能我如今还在迷茫的找职业定位。”事隔七八年。当我昨天中午再次见到老朋友冉红宇的时候&#xff0c;他第一句话是这样说的。冉红宇&#xff0c;丰羽创业孵化器的合伙人。这个位于最知名的北京创业一条街上的孵化器&#xff0c;正在孵化三个项目。当…...

云南网站建设肖庆华/免费发广告的平台有哪些

【案例】Oracle等待事件resmgr:cpu quantum 产生原因和解决办法 Oracle研究中心案例分析&#xff1a;发现一个关于Oracle数据库等待事件 resmgr:cpu quantum 的案例。 本站文章除注明转载外&#xff0c;均为本站原创&#xff1a; 转载自love wife & love life —Roger 的Or…...