理解HashMap的几个关键点

Infineon MOSFET开关损耗计算实战指南 本文是英飞凌MOSFET开关损耗计算的实战指南。针对MOSFET发热问题,文章深入剖析了开关损耗的产生机理,并基于Infineon数据手册的关键参数,手把手推导了开通与关断损耗的工程计算公式。同时,指南强调了栅极电阻、寄生参数等实际因素对损耗的影响,并提供了从理论计算到实测优化的完整路径,帮助工程师精准评估与优化电源设计。 阅读详情

什么是HashMap?

HashMap是一个散列表,存储的内容为键值对的映射(key-value),由于key存放在Set集合中,意味着key值不允许重复,但是key和value都允许为null。HashMap继承AbstractMap抽象类,实现了Map、Cloneable、Serializable接口,允许克隆和序列化。另外,HashMap是非线性安全的,键值对的映射也不是有序的。

HashMap的工作原理?

我们在使用HashMap的时候,最常用的就是get(key)和put(key,value)方法,分别是插入或者取出键值对。而这两个方法的实现并不简单。首先我们需要知道,在HashMap类中,有一个静态内部类Entry,这个类才是真正存放key和value的地方,HashMap有一个成员属性Entry<K,V>[] table 就是用于存放Entry。get和put方法就是通过hashCode()方法求出key值的hashCode,再根据hashCode将键值对存放到table中。我们再深入看看Entry类的成员属性,会发现有一个Entry<K,V> next属性,这就意味着Entry实际上是一个单链表!为什么需要设计为单链表?我们再看下文分析。

当两个对象的hashCode相同怎么办?

好了,现在就可以解决为什么Entry要设计为单链表,就是用于解决hashCode冲突问题!这里,我先提出一个关键点:HashMap是通过hashCode()方法找出我们bucket(也就是table数组中的位置),而equals()是用于从Entry链中找到我们的key值。很多时候都会混淆这两个方法,误以为就是通过hashCode()确定我们存放的key-value。如果我们将两个key的hashCode值相同的对象放进HashMap时,这时候,就先确定hashCode对应的table下标,然后调用equals()方法对两个hashCode相同的key值进行比较(也就是比较它们的内存地址是否相等),如果相等,用新的value替换旧的value,如果不相等,则将新的key-value插到Entry链的头部,之所以插到头部,是为了避免插到尾部而遍历链表导致额外的o(n)时间复杂度。取出key-value的原理也是差不多,确认hashCode后,从Entry链的头部遍历到尾部,逐个用equals()比较,找到对应的key-value。

如何有效地减少冲突?

通常,我们建议使用String和其他包装类作为key更好。原因是String类声明为final,是不可变的,同时,String类重写了hashCode()方法和equals()方法,包装类也类似。如果存放的key对象经常改变,就会增大冲突的概率,又或者我们设计的hashCode()方法和equals()方法不合理,也会导致冲突概率增加。

额外提醒一下Java中对于hashCode和equals()是这样定义的:如果两个对象满足x.equals(y)==true,那么它们的hashCode也应该相等。同时对于equals()方法的设计应该遵循必须满足自反性(x.equals(x)必须返回true)、对称性(x.equals(y)返回true时,y.equals(x)也必须返回true)、传递性(x.equals(y)和y.equals(z)都返回true时,x.equals(z)也必须返回true)和一致性(当x和y引用的对象信息没有被修改时,多次调用x.equals(y)应该得到同样的返回值),而且对于任何非null值的引用x,x.equals(null)必须返回false。

如何设计HashMap的容量

关于HashMap的容量有几个关键的属性:①负载因子(loadFactor):默认值为0.75,也就是当容量达到75%时,和其他集合类一样需要进行扩容,HashMap每次扩容一倍。②初始容量(initialCapacity):创建HashMap的初始容量大小,默认值为16。③阈值(threshold):当容量大小达到该值即进行扩容,其中threshold=loadFactor*initialCapacity。当HashMap大小超过负载因子的大小,就会调用rehash()方法,对所有Entry重新计算hashCode值,这个代价是有非常高的!所以,合理地设计负载因子和初始容量很关键,一般来说,当负载因子较大时,rehash的可能性就会降低,占用的内存空间也会减少,但是每一条Entry链的大小就会增加,导致搜索时间变长,以时间换空间;反之,即以空间换时间,具体还需要根据实际情况而设定。

为什么说HashMap是非线性安全的?

我们对HashMap进行rehash(),原Entry链逆序,1->2->3就会变成3->2->1,当两个或以上的线程同时对HashMap实例进行rehash时,就有可能出现1->2->3->4死锁情况。详细可以阅读这篇博客。


以上的分析其实都是基于JDK 1.7之前的版本,在JDK 1.8之后,HashMap的变化还是挺大的,这里简单分析一下两个版本的HashMap有哪些不一样,具体可自行Baidu,Google。

我们知道JDK 1.7中,HashMap是采用数组+链表的方式存储键值对,当冲突比较多的时候,由于链表的遍历时间复杂度为o(n),势必会大大影响get()方法的性能,所以,JDK 1.8采用数组+链表+红黑树来存储键值对。具体为,当某一条链大小超过8,将会转换为红黑树,红黑树的查找时间复杂度是o(logn),得到较大的优化。而且,Entry类改名为Node,也就是改为树节点了。

这里写图片描述

关于HashMap与HashTable、ConcurrentHashMap的区别(简单分析)

①HashMap与HashTable
相比于HashMap,HashTable是线程安全的,使用了Synchronize关键字进行控制,同时HashTable不仅实现了Map接口,还继承了Dictionary类,而Dictionary依赖于Enumeration接口,使得HashTable不仅可以使用迭代器遍历,也可以通过Enumeration遍历。HashTable不允许key=null和value=null;
②HashMap与ConcurrentHashMap
为了保证线程安全,而又不至于像HashTable使用重量锁Synchronize,ConcurrentHashMap采用了分段锁技术。ConcurrentHashMap实际上是一个Segment数组,每一个Segment通过继承ReentrantLock进行加锁,这样就保证了在多线程下,每个线程只对自己访问的Segment加锁,而不影响其他线程对其他Segment的操作,相比HashTable性能更优越。每个Segment其实和HashMap的结构有点相似,JDK 1.7之前采用数组+链表,JDK1.8采用数组+链表+红黑树,与HashMap有所不同的是,为了保证并发安全,Node<K,V>中对于V和next都声明为volatile。详细可阅读Java7/8 中的 HashMap 和 ConcurrentHashMap 全解析
这里写图片描述

资料参考
http://www.importnew.com/7099.html
https://segmentfault.com/q/1010000005602326
http://www.importnew.com/22011.html
http://www.cnblogs.com/skywang12345/p/3310835.html

中职网络安全2021年国赛Wireshark流量分析题目解析 中职网络安全Wireshark流量分析题目解析 阅读详情

相关推荐

反激开关电源变压器设计实例讲解(定明芳)

内容来自《反激变压器的设计》(定明芳主讲)。 定名芳老师主要讲了10步,最后应该还有一步,线径的选择已经绕制方式。这里进行了记录整理,把一些公式来源进行了推导。所有的设计都是基于理论计算。 1.确定电源规格 2.确定工作频率和最大占空比 3.计算匝比(利用伏秒平衡原则) 此处插入解释一下伏秒平衡,根源是磁通量平衡。该原则可以用来检查MOS管耐压是否够。 4.计算初级线圈峰值电流 基于CCM模式计算的。ip1是开关管要关闭时的峰值电流,ip2是开关管开始导通时的起始电流。因为时CCM模式,所以,ip

ydgd118的博客 5万+

HashMap源码解析——关键属性

HashMap类中的一些关键属性:ttransient Node<K,V>[] table;//存储元素的实体数组 transient int size;//存放元素的个数 int threshold; //临界值 当实际大小超过临界值时,会进行扩容threshold = 加载因子*容量 final float loadFactor; //加载因子 transient int modCount;

Linn 3257

STM32串口通信实战:从CubeMX配置到printf重定向全解析

串口通信是嵌入式系统中最基础且广泛使用的数据交换方式,它基于异步串行通信原理,通过TX(发送)和RX(接收)两根信号线实现设备间的全双工通信。其技术价值在于协议简单、硬件成本低、可靠性高,是单片机与上位机调试、传感器数据采集、设备控制等场景的首选方案。在STM32等ARM Cortex-M系列MCU中,USART外设通过硬件自动处理时序,大大减轻了CPU负担。本文聚焦于嵌入式竞赛与开发中的高频需求,以STM32G431RBT6为例,详解通过CubeMX配置USART1、实现按键触发数据发送、并完成print

weixin_30603633的博客 545

HashMap 这一篇就够了

HashMap

QG 626

Windows 11 上 WSL2 安装 Ubuntu 22.04 保姆级教程(含桌面环境配置)

本文提供在Windows 11上通过WSL2安装Ubuntu 22.04并配置桌面环境的详细教程。涵盖WSL2核心安装、性能调优、Xfce桌面环境部署以及开发环境集成,帮助开发者构建高效、无缝的Windows-Linux混合开发工作站。

Jerry的专栏 633

VisionMaster脚本调试(VS)

使用VS调试VisionMaster 脚本

yu_fujiang的专栏 3293

HashMap剖析

一、HashMap概述     HashMap是基于哈希表的Map接口的实现,此实现提供所有可选的映射操作,并允许使用null值和null键。(除了不同步和允许使用null之外,HashMap类与HashTable大致相同)此类不保证映射的顺序,特别是它不保证该顺序恒久不变。     HashMap是非同步的,但是我们也可以通过Collections.synchronizedMap(has

hou_yaxin的博客 203

模拟电路综合笔试题解析

本专栏预计更新60期,当前为第10期,文章约6000字,旨在帮助读者掌握模拟电路笔试的核心知识点与实战技巧。文章分为五个章节,涵盖基础理论、高频考点、大厂题目解析等内容。首先,文章详细解析了DC-DC与LDO的区别及选型依据,并通过真题分析帮助读者理解其应用场景。接着,文章深入探讨了运放电路设计、同步降压电路设计等高频考点,并结合实际案例提供解决方案。此外,文章还分享了特斯拉、华为、大疆等大厂的面试题及解析,帮助读者应对复杂电路设计挑战。最后,文章总结了模拟电路设计中的关键技巧与优化方法,为读者提供全面的笔

启芯硬件的博客 469

HashMap的工作原理

HashMap主要是用来处理键值对数据,随着JDK版本的更新,JDK1.8对HashMap的底层也做了一些优化,HashMap是基于哈希表对Map接口的实现类,它的特点是访问数据速度快,并且不是顺序来遍历的,HashMap提供所有的可选的映射操作但是不能保证映射顺序不变并且允许插入空值和空键,HashMap本身并不是线程安全的,当存在多线程同时写入的时候可能会导致数据不一致的情况 1.HashMap中的关键属性 第一个属性loadFactor它是负载因子,默认值是0.75,表示在扩容前HashMap

qq_31587111的博客 2333

SolidWorks速成教程P3-5【零件 | 第五节】——异形孔向导&线性阵列&镜像

这节介绍异形孔向导、线性阵列、镜像。

嵌入式阿齐Archie 6073

DeerFlow 系列教程 第十一篇 | Sandbox 沙箱与 Memory 记忆——安全执行与持久认知

用户请求│▼Lead Agent├── 系统提示词组装│ ├── <memory> 段 ← Memory 系统注入用户记忆│ ├── <skill_system> 段│ └── <subagent_system> 段│├── 工具调用│ ├── read_file ├── Sandbox 系统提供隔离执行│ ├── write_file├── 路径虚拟化 + 安全验证│└── 对话结束│▼│├── 过滤消息(去除工具调用中间步骤)├── 检测纠正/强化信号。

weixin_43674738的博客 161

HashMap面试,看这一篇就够了

历史热门文章: 七种方式教你在SpringBoot初始化时搞点事情 Java序列化的这三个坑千万要小心 可以和面试官聊半个小时的volatile原理 Java中七个潜在的内存泄露风险,你知道几个? JDK 16新特性一览 啥?用了并行流还更慢了 InnoDB自增原理都搞不清楚,还怎么CRUD? 前言 在一场面试中最能打动面试官的其实是细节,候选人对细节的了解程度决定了留给面试官的印象到底是“基础扎实”还是“基础薄弱”,如果候选人能够举一反三主动阐述自己对一些技术细节的理解和总结,那无疑是面试过程中.

DD_Dddd的博客 2万+

NVIDIA AI 学习与认证指南:从入门到精通

NVIDIA的AI学习与认证体系,凭借其先进的技术背景、丰富的课程资源以及强大的行业认可度,已成为AI学习者和从业者的宝贵资源。通过深入学习NVIDIA的课程和获得认证,学习者可以快速掌握最前沿的AI技术,提升自己的职业竞争力。从基础课程到专业认证,NVIDIA为不同层次的学习者提供了量身定制的学习资源,帮助他们掌握AI的核心技能,提升职业竞争力。是其中的一个亮点,它结合了信息检索与生成式AI的能力,使AI可以从外部知识库中实时提取信息,生成更具深度和准确性的内容。,帮助学习者快速掌握该领域的核心技术。

高校图书馆高级系统架构师/研究馆员,推动高校AI从概念演示到可评审、可交付、可运维:路线图与立项评审、PoC交付、评测回归与上线运维(Baseline/Eval/Ops)。 1876

深入理解HashMap

深入剖析了HashMap的实现原理和源码

mazouri的博客 5353

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

hashMap的理解

hashMap的理解一、HashMap简介put原理get原理二、哈希碰撞三、与HashTable的区别1. HashTable介绍2. 区别最后、常见问题一、HashMap中的“死锁”是怎么回事 一、HashMap简介 HashMap是基于哈希表实现的,每一个元素是一个key-value对,无序,不可重复。 HashMap是非线程安全的,只是用于单线程环境下,多线程环境下可以采用concurrent并发包下的concurrentHashMap。 HashMap 实现了Serializable接口,因此它

weixin_45671337的博客 2911

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

hashmap是散列表吗_用几个问题来理解HashMap

在Java面试时,HashMap被问到的机率还是很大的,当面试管问:“你对HashMap的理解有多少”时,你是否会呆滞一下。也许你有看过HashMap相关的介绍,甚至有看过源码并分析过。但因时光流逝,对HashMap的理解就变成了碎片记忆,思路混乱,不知从何说起。我以面试官的身份进入一问一答。面试官的习惯就是刨根问底,因为是面试回答,所以我这边对于回答并没有太详细讲解,毕竟面试中,哪有那么多时间听...

weixin_39919165的博客 356

HashMap源码理解

HashMap源码的理解

尹凯文的博客 2829

【HashMap全面知识点】— 快速理解HashMap

本文讲解了 HashMap 的核心知识,包括其定义(实现 Map 接口,存键值对,允许 null 键值,非线程安全且无序)与核心参数(容量默认 16 且为 2 的幂、负载因子默认 0.75 等)。还阐述底层数据结构演进(JDK1.7 为数组 + 单向链表,JDK1.8 新增红黑树)、核心算法(哈希值与索引计算、put 方法流程、扩容机制),对比 JDK1.7 与 1.8 差异,分析并发隐患及解决方案,列举高频面试题,并给出实践建议,帮助读者全面理解 HashMap。

Mr.Ja的博客 2205

HashMap理解

1.由数组+链表的结构改为数组+链表+红⿊树。 2. 优化了⾼位运算的hash算法:h^(h>>>16) 3. 扩容后,元素要么是在原位置,要么是在原位置再移动2次幂的位置,且链表顺序不变。【当超过限制的时候会resize,然而又因为我们使用的是2次幂的扩展(指长度扩为原来2倍),所以,元素的位置要么是在原位置,要么是在原位置再移动2次幂的位置】 1. 底层数据结构? JDK 1.7: Table数组+ Entry链表 JDK1.8: Table数组+ Entry链表/...

weixin_35821291的博客 860

HashMap的理解

Hash 值的范围值比较大,使用之前需要先对数组的长度取模运算,得到的余数才是元素存放的位置也就是对应的数组下标。JDK 1.7中的HashMap底层是hash数组和单向链表实现,数组中的每个元素都是链表,由Node内部类(实现Map.Entry<K,V>接口)实现,HashMap通过put&get方法存储和获取。3.如果K的hash值在HashMap中存在,且它们两者equals返回false,则插入链表的尾部(尾插法)或者红黑树中(树的添加方式)。当链表长度超过阈值(8)时,将链表转换为红黑树。

2401_85327573的博客 776

python hashmap函数_理解HashMap

HashMap源码分析基于JDK7的HashMap源码分析类的介绍下面的类介绍是从源码的英文翻译来的HashMap是基于哈希表实现的Map接口实现类。这个实现提供所有的map相关的操作,允许使用null的键和null的值。(HashMap与Hashtable大致是一样的,只是HashMap是不同步的,且它允许你null的键和值。);另外,HashMap内部元素排列是无序的。假设哈希函数能将元素合理...

weixin_39518002的博客 2327

深入理解 HashMap的数据结构

HashMap 是基于哈希表的 Map 接口实现,它存储键值对(key-value pairs),允许 null 键和 null 值,并且不保证元素的顺序。// 基本使用示例// 输出: 25// 自定义键类必须正确实现 hashCode() 和 equals()@Override@Override// 使用自定义对象作为键在时间和空间成本上做了折衷,0.75 提供了较好的性能平衡。数据结构:数组 + 链表/红黑树(Java 8+)哈希函数:通过高位异或减少冲突。

Z123C456H的博客 1016

对HashMap的理解

JDK1.7版本的HashMap

new2MySQL的博客 926

HashMap的底层简单理解

概述 HashMap基于Map接口实现,元素以键值对的方式存储,并且允许使用null建和null值,因为key不允许重复,因此只能有一个键为null,另外HashMap不能保证放入元素的顺序,它是无序的,和放入的顺序并不能相同。HashMap是线程不安全的。 数据结构 HashMap底层是以数组+链表方式进行存储,通过对key的hash计算和数组长度得到value在数组中存储的位置(index = hash值 & (length - 1))。当不同的ke...

weixin_42640226的博客 2742

面试必问的HashMap-1.1:HashMap几个关键点分析

HashMap都不算什么特别的,这里整理下我的理解。 分析HashMap就不得不说下数据结构, 首先Java中有几种数据结构:数组、链表、树 数组的话:查询效率高 链表新增效率高。 牛逼的是,我们的HashMap的数据接口就比较吊了,他会把数组和链表的优势结合起来。 数组: int[] aa 这就是一个数组 链表: 单向链表,其实就主要是存了一个数据和指向下...

u010953880的专栏 234
上一篇: 事务隔离级别--脏读,不可重复读,幻读
下一篇: Volatile,Synchronized,Lock
HamalAlpha
博客等级 码龄11年 5粉丝 31原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值