java集合之HashMap底层源码扩容机制探究

多臂老虎机——入门强化学习 多臂老虎机(Multi-Armed Bandit,MAB)问题是强化学习的经典入门例子,也是理解探索与利用(exploration-exploitation)平衡的重要案例。 阅读详情

先简单介绍一下结论:

  • HashMap默认初始化容量大小为16,加载因子为0.75
  • 当容量大于临界值(=容量*加载因子)时会扩容为原来的两倍

测试代码如下:

		//扩容机制的探究
        HashMap hashMap = new HashMap();

        for (int i = 0; i < 12; i++) {
            hashMap.put(i,i);
        }

设置断点跟入,首先进入构造函数如下:
在这里插入图片描述
初始化后的hashMap如下:
在这里插入图片描述
添加数据进行第一次扩容:
在这里插入图片描述
在这里插入图片描述
putVal()方法需要hash值,以下是根据key计算hash值的函数
在这里插入图片描述
下面来介绍putVal函数,给出源码:

final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
                   boolean evict) {
        Node<K,V>[] tab; Node<K,V> p; int n, i;
        if ((tab = table) == null || (n = tab.length) == 0)
            n = (tab = resize()).length;
        if ((p = tab[i = (n - 1) & hash]) == null)
            tab[i] = newNode(hash, key, value, null);
        else {
            Node<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) // -1 for 1st
                            treeifyBin(tab, hash);
                        break;
                    }
                    if (e.hash == hash &&
                        ((k = e.key) == key || (key != null && key.equals(k))))
                        break;
                    p = e;
                }
            }
            if (e != null) { // existing mapping for key
                V oldValue = e.value;
                if (!onlyIfAbsent || oldValue == null)
                    e.value = value;
                afterNodeAccess(e);
                return oldValue;
            }
        }
        ++modCount;
        if (++size > threshold)
            resize();
        afterNodeInsertion(evict);
        return null;
    }

现在是首次添加数据,我们来分析如何执行以上代码
在这里插入图片描述
首次扩容将会调用resize()函数,跟入:
在这里插入图片描述
在这里插入图片描述
首次扩容就到此完成了,我们回到putVal函数继续跟入看如何进行添加元素

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
顺便说一下如果要添加元素,计算得到的索引处有元素了,则如何添加:就是以链表的形式添加,具体如下:
第一种情况:
在这里插入图片描述

第二种情况:
在这里插入图片描述
ps:HashMap底层数据结构从数组+链表转化为数组+红黑树的条件为:

1.链表长度到达8
2.数组长度到达64

同时满足以上两个条件才会树化为数组+红黑树

第三种情况:
在这里插入图片描述
第一和第三两种情况替换value的代码:
在这里插入图片描述

最后进行一次判断添加新元素后的容量是否大于临界值:
在这里插入图片描述
以上就是首次添加元素HashMap进行扩容的底层源码实现,由上面探究可知当HashMap的容量到达12时就会触发新一轮的扩容,接下来我们继续来底层源码探究如何实现:

测试代码:

 //扩容机制的探究
        HashMap hashMap = new HashMap();

        for (int i = 0; i < 12; i++) {
            hashMap.put(i,i);
        }
        hashMap.put(12,12);

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
介绍到此结束,希望能帮助到您对于集合源码的学习,强烈建议自己动手debug几遍,只有把每个过程为什么这么走搞懂了,才算真正的学会了,谢谢

手把手教你ensp仿真搭建校园网(含防火墙及无线网络)系列(一)校园网核心交换机配置 本系列博客将带你从零开始,使用 华为 eNSP(Enterprise Network Simulation Platform) 仿真搭建一个完整的校园网络,涵盖 核心层、汇聚层、接入层、防火墙安全策略、无线AC+AP组网 等实战场景。无论你是网络初学者还是希望深化实战经验的工程师,都能通过本教程掌握企业级网络的规划、配置与排错技巧。 阅读详情

相关推荐

最新Mamba环境配置教程:从CUDA到causal-conv1d的完整安装流程

本文提供最新Mamba环境配置教程,涵盖从CUDA到causal-conv1d的完整安装流程。针对深度学习领域的长序列处理需求,详细指导如何正确配置CUDA工具链、安装PyTorch及关键依赖causal-conv1d,解决常见报错问题,并验证mamba-ssm集成效果。

bush的博客 415

HashMap之扩容原理

一、什么是HashMap? HashMap 数据结构为 数组+链表(JDk1.7),JDK1.8中增加了红黑树,其中:链表的节点存储的是一个 Entry 对象,每个Entry 对象存储四个属性(hash,key,value,next) 二、为什么要使用HashMap? 对于要求查询次数特别多,查询效率比较高同时插入和删除的次数比较少的情况下,通常会选择ArrayList,因为它的底层是通过数组实现的。对于插入和删除次数比较多同时在查询次数不多的情况下,通常会选择LinkedList,因为它的底层是通过链

Mr_yeml的专栏 2万+

Materials studio中的简单聚合物的建立及盒子的弛豫

涉及模块 Amorphous Cell-construction Forcite-caculation Build Polymers-Homopolymer

快乐学术猿 3万+

HashMap扩容机制以及尾插法

1. resize定义 当HashMap中的元素越来越多的时候,碰撞的几率也就越来越高(因为数组的长度是固定的),所以为了提高查询的效率,就要对HashMap的数组进行扩容,数组扩容这个操作也会出现在ArrayList中,所以这是一个通用的操作,很多人对它的性能表示过怀疑,不过想想我们的“均摊”原理,就释然了,而在HashMap数组扩容之后,最消耗性能的点就出现了:原数组中的数据必须重新计算其...

傅红雪的专栏 2万+

黑马Java第二阶段:JavaWeb(笔记)

黑马Java第二阶段:JavaWeb(笔记)

chen的博客 5649

VS2022+Qt6保姆级环境配置指南:从插件安装到项目互通全流程

本文提供VS2022与Qt6深度整合的全流程指南,涵盖环境配置、插件安装、项目互通等关键步骤。详细解析编译器版本匹配、跨IDE协作方案及效能优化技巧,帮助开发者高效搭建C++界面设计开发环境,实现软件项目无缝互通。

zero1的博客 731

HashMap详解(扩容机制、底层结构、适用场景)

1.7:数组+链表 (由于是链表长度长了。查询效率不高。所以在设计初衷1.7的hash算法更复杂。数据也更散列)1.8:数组+链表+红黑树(JDK8中即使用了单向链表,也使用了双向链表,双向链表主要是为了红黑树相关链表操作方便,应该在插入,扩容,链表转红黑树,红黑树转链表的过程中都要操作链表),HashMap的扩容是通过调用resize()方法实现的。 java1.8+在扩容时,不需要重新计算元素的hash进行元素迁移。而是用原先位置key的hash值与旧数组的长度(oldCap)进行"与"操作。

qq_64680177的博客 3289

单细胞分析实录(12): 如何推断肿瘤细胞

公众号后台回复20210418,获取本文的测试数据 1. 回顾 前面我已经讲解了inferCNV的基本用法,这一节继续学习:如何推断肿瘤细胞。本文应该是到目前为止,全网最详细的帖子(之一)。 关于肿瘤细胞的推断,比如研究上皮细胞起源的肿瘤,我见过的一些做法如下 简单粗暴型:将来源肿瘤病灶的所有上皮细胞都看成是肿瘤细胞 看CNV:将来源于肿瘤病灶的上皮细胞和参考细胞比较,将那些有明显CNV的细胞看作肿瘤细胞 看表达特征:考虑到有的肿瘤细胞可能没有CNV层面的变化,有的文章会根据肿瘤与正常的表达谱来区分是.

TOP生物信息 1万+

HashMap的扩容机制

①:先生成新数组; ②:遍历老数组中的每个位置上的链表或红黑树; ③:如果是链表,则直接将链表中的每个元素重新计算下标,并添加到新数组中去; ④:如果是红黑树,则先遍历红黑树,先计算出红黑树中每个元素对应在新数组中的下标位置; a:统计每个下标位置的元素个数; b:如果该位置下的元素个数超过了8,则生成一个新的红黑树,并将根节点添加到新数组的对应位置; c:如果该位置下的元素个数没有超过8,那么则生成一个链表,并将链表的头节点添加到新数组的对应位置; ⑤:所有元素转移完了之后,将新数组赋值给H

eg1107的博客 1万+

8、对比 LightGBM、XGBoost 和深度学习

本文对比了LightGBM、XGBoost和深度学习模型(特别是TabTransformer)在处理表格数据时的性能差异。从模型复杂度、数据准备、训练时间、准确性和适用场景等方面进行分析,重点探讨了三者在人口普查收入预测任务中的表现。文章详细介绍了XGBoost与LightGBM的核心特性与区别,深入讲解了TabTransformer的架构与实现,并涵盖了分类特征编码、缺失值处理和类别不平衡等关键数据预处理技术,为选择合适的表格数据建模方法提供了实践指导。

julia4scientist的博客 120

玩转 InternVL3.5 轻量级实战:从部署到优化的全记录

玩转 InternVL3.5 轻量级实战:从部署到优化的全记录

jacke121的专栏 626

HashMap的扩容

HashMap初始化 在JDK1.8中,定义了HashMap的初始化过程,我们看看他的源码是如果定义这个初始化过程 可以看到,它的构造方法中传入了两个参数,一个是初始化容量,一个是加载因子,默认是0.75f HashMap(int initialCapacity, float loadFactor) 但是这个容量最终调用了另一个构造方法 这个threshold的成员变量,就是触发HashMap扩容的阈值,当HashMap的数据量达到或超过threshold时,就会扩容。 我们再往下看这个tableSi

张三李四王五老六 6203

接口电路设计的关键要点

接口电路设计是嵌入式硬件开发的核心环节,本文系统阐述了五大关键设计要点:1)电平匹配技术,详细分析了3.3V/5V系统互连方案及转换电路计算;2)阻抗匹配原理,包括高速信号反射机制及差分信号处理;3)滤波与去耦设计,提出多级电容配置和"先电容后过孔"布局原则;4)接地设计规范,重点说明模拟/数字地分离及高速信号回流路径;5)防护电路设计,涵盖防反接、过流保护及ESD防护方案。文章通过具体计算公式、器件选型指南和布局技巧,为接口电路设计提供了系统化的解决方案,并附有设计检查清单和典型问题分

weiyvyy的博客 453

Java 集合面试题从数据结构到 HashMap 源码剖析详解及常见考点梳理

摘要 Java集合框架是开发中的核心知识,本文从基础概念到源码层面进行了系统解析。首先介绍了Collection和Map两大接口体系,对比了ArrayList、LinkedList、HashSet等实现类的特点。重点剖析了HashMap的底层数据结构演变:JDK1.7采用数组+链表结构,而JDK1.8优化为数组+链表+红黑树组合,有效提升了查询性能。详细解读了HashMap的关键源码实现,包括哈希计算、扩容机制等核心流程。最后通过订单管理系统的实际案例,展示了HashMap的高效应用场景。全文既有理论深度,

sss191s的博客 1021

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

java集合的扩容机制

总结 ArrayList 和Vector默认加载因子都是1(元素满了才扩展容量).默认容量都是10;但是ArrayList 在jdk1.8时默认为空,当添加元素时,才初始化为10个容量。 ArrayList 默认初始容量为10,(jdk8的时候底层Object[] elementData数组初始化为{},并没有创建长度为10的数组。在add元素时才创建了10个容量。) 线程不安全,查询速度快     底层数据结构是数组结构     扩容增量:原容量的 0.5倍,新容量为原容量的1.5倍。     如 Ar

weixin_38568503的博客 9057

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Java集合之HashMap源码详解

HashMap的源码详细解析

个人博客,欢迎收藏。 1930

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

深入解析Java:HashMap扩容机制全过程深度剖析

HashMap是Java开发中最常用的集合,扩容机制是HashMap的核心灵魂,也是面试高频考点。很多开发者只知扩容会重新分配数组,却不懂何时触发扩容、容量如何计算、数据如何迁移、JDK1.8做了哪些优化。本文从基础概念、触发时机、容量计算、完整流程、源码解析、流程图六大维度,彻底拆解HashMap扩容机制,帮你一次性吃透这个核心知识点!扩容(resize):当HashMap中元素数量达到阈值,无法再存储更多数据时,创建一个新的更大的数组,将原数组数据重新计算位置并迁移到新数组,替换旧数组的过程。

✨ 欢迎来到【Seal ^_^ 的优快云博客】!✨ 2601

【java集合体系中各集合的扩容机制】

在之前提到多数据存储的三种方式:数组、链表、树,它们单独使用时都非常不方便,因此存在一些集合接口提高了多数据存储的能力。集合分为单列集合和双列集合,其下的一些实现类都存在自己的扩容机制,本篇介绍其扩容机制。

m0_54230514的博客 3265

深入剖析HashMap:理解Hash、底层实现与扩容机制

Key的存储方式是基于哈希表的HashMap是 Map 接口 使用频率最高的实现类。允许使用null键和null值,与HashSet一样,不保证映射的顺序。所有的key构成的集合是无序的、唯一不可重复的。所以,key所在的类要重写:equals()和hashCode()所有的value构成的集合是Collection:无序的、可以重复的。所以,value所在的类要重写:equals()一个key-value构成一个entry所有的entry构成的集合是Set:无序的、不可重复的。

SevenCoding的博客 1623

HashMap扩容机制的个人理解及它的底层实现

Key的存储方式是基于哈希表的,HashMap是 Map 接口 使用频率最高的实现类。允许使用null键和null值,与HashSet一样,不保证映射的顺序。所有的key构成的集合是无序的、唯一不可重复的。所以,key所在的类要重写:equals()和hashCode()所有的value构成的集合是Collection:无序的、可以重复的。所以,value所在的类要重写:equals()

chengxuyuanlaow的博客 1292

Java常用集合扩容机制及源码解析

Java集合扩容机制以及源码分析,祝你突破面试大关

日常技术分享 1630

集合扩容问题(ArrList为例,常用集合扩容机制) -- JAVA 基础

今天刚好遇到一个关于集合扩容的问题,正好借机整理一下: 当底层实现涉及到扩容时,容器或重新分配一段更大的连续内存(如果是离散分配则不需要重新分配,离散分配都是插入新元素时动态分配内存),要将容器原来的数据全部复制到新的内存上,如果是每增加一个元素就复制一次,这无疑使效率大大降低。这里的扩容就是当当前容器的内存不足或者达到加载因子设置的系数时,需要对容器进行一次合适的扩建(加载因子的系数小于

qishun2xiao的博客 1万+

集合【高级篇】ArrayList、HashMap 、ConcurrentHashMap的底层源码以及相关的扩容机制

文章目录前言一、ArrayList 源码+扩容机制1、ArrayList 简介2、Arraylist 与 LinkedList 区别3、Arraylist核心代码解读4、ArrayList 扩容机制分析二、使用步骤总结 前言   我之前这篇博客 Java高级----List集合、Set集合、Map集合总结 详细介绍了Java中集合相关的基础知识,本篇博客就深入聊聊集合ArrayList、HashMap 、ConcurrentHashMap的底层源码以及相关的扩容机制~ 一、ArrayList 源码+扩容

NanYII_的博客 712

JAVA中集合的各种扩容机制

故开始使用空参构造创建的ArrayList为一个空数组,当首次添加元素的数量小于DEFAULT_CAPACITY即10的时候java底层则创建一个容量为10的数组,若开始添加元素大于十则根据具体添加元素数量来创建一个大小刚好合适的数组。当ArrayList有初始元素时添加元素后集合大小小于DEFAULT_CAPACITY即10则不扩容,若大于DEFAULT_CAPACITY即10时判断添加元素数量是否多于旧容量的一半,若小于则进行1.5 倍扩容,若大于则根据添加元素数量来创建一个大小刚好合适的数组。

2401_89496570的博客 1450

java中各种集合的扩容机制记录总结

参考:https://www.cnblogs.com/lq147760524/p/6713677.html JAVA中的部分需要扩容的内容总结如下:第一部分:HashMap 、HashSet、Hashtable第二部分:ArrayList、Vector、CopyOnWriteArrayList第三部分:StringBuffer、StringBuilder先从以下几个源码方面分析:(JDK1.8)1...

wwwtotoro的博客 6264

【集合框架HashMap扩容机制】

本文深入解析了Java中HashMap的核心实现机制。从数据结构设计(数组+链表+红黑树)到扩容流程,详细剖析了默认容量16、加载因子0.75、树化阈值8和64等关键参数的设计原理。通过JDK1.7与1.8的对比,重点讲解了尾插法优化、位运算rehash等性能改进。文章还揭示了基于泊松分布的参数设计思想,并给出了预设容量、避免频繁put等最佳实践建议。全文从源码层面展示了HashMap在数据结构、概率统计与性能优化上的精妙权衡,是理解Java集合框架底层实现的重要参考。

weixin_64178283的博客 1246
上一篇: 成功解决 Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Requ
下一篇: 不小心卸载win10自带的word、excel等解决方法
JavaWizard-M
博客等级 码龄6年 3159粉丝 148原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值