[Java]HashMap源码分析

java HashMap 源码分析 一、HashMap内部的数据结构是什么? 数组+单向链表 二、怎么验证内部结构是数组和单向链表? a、数组:通过HashMap源码知道、HashMap内部有个属性 transient Node<K,V>[] table b、单向链表:内部类Node里面维护了一个next的属性 Node<K,V> next,是指向下一个节点的; 三、HashMap里面为什么会有hash的存在?hash计算的理解? 我们先看下我的事例代码 public class HashMapDemo { 阅读详情

HashMap 是一种基于Hash表的Map接口实现,关于HashMap有几个特别重要的要点。

capacity:总容量,但表示散列表中的总的位置数目

threshold:hash表中,所能够容忍被散列的最大值

load_factor:负载系数 HashMap中默认的系数为0.75, threshold / capacity = load_factor

size:所放进HashMap里面的所有[key:value]对

Hash:散列技术,好的散列算法能让所有元素均匀的散列在表中。散列函数能使对一个数据序列的访问过程更加迅速有效,通过散列函数,数据元素将被更快地定位。




HashMap中是 是使用 key进行散列,散列如下

 static final int hash(Object key) {
        int h;
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }

key为null 则hash值为0 否则计算hash值

那么这样得出的hash值一般得到大于capacity大小的数

然后经过如下得到准确的散列首地址

 if ((p = tab[i = (n - 1) & hash]) == null)
            tab[i] = newNode(hash, key, value, null);
n为数组的大小即capacity,我们之前说过n 为2的次方数,所以当n-1的时候得到的 可定是能够以 000...1111表示的二进制数

然后与hash相与,那么得到的值必定是在数组长度之内


那么我们简单的分析下put(key,value)这个函数:

    public V put(K key, V value) {
        return putVal(hash(key), key, value, false, true);
    }

    /**
     * Implements Map.put and related methods
     *
     * @param hash hash for key
     * @param key the key
     * @param value the value to put
     * @param onlyIfAbsent if true, don't change existing value
     * @param evict if false, the table is in creation mode.
     * @return previous value, or null if none
     */
    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;
    }

put(key,value)这个函数调用final V putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict)

这里需要说明的是 实际上 在new HashTable()的时候  散列数组是没有初始化的,仅仅初始了loadFactor。

所以在对map进行操作的时候 都会实现判断是否 为null,为空则会初始至默认大小。

所以这里第一步是进行hash散列数组的初始化,然后判断所散列的地方是否存在已被散列值,不存在则直接放入node

如果存在key是相等的 取得该引用  否则 判断该类型是否为TreeNode 之前说过 当某一个散列堆簇超过8个时候 会进行二叉树化,这里的结点就是二叉树的根结点。否则直接到尾部插入。

插入进去之后会返回旧值,如果旧值存在的话。


其他的方法也大同小异,这里就不加赘述了。



相比HashTable来说,HashTable是同步的,所以性能会差上很多,同时HashTable不能插入null的键值对。

HashSet也是基于HashMap实现的。


深度剖析Java HashMap:源码分析、线程安全与最佳实践 Java中的HashMap是最常用的数据结构之一,在实际开发中起着至关重要的作用。本文将详细探讨HashMap的工作原理、源码分析、线程安全问题、以及扩容机制等方面。 阅读详情

相关推荐

Java中的常见五种map容器源码分析总结(HashMap、Hashtable、ConcurrentHashMap、LinkedHashMap、TreeMap)

  断断续续写了半个月,今天终于把TreeMap容器中的红黑树搞定了,现在来水一篇又快又短的Java Map容器总结博客 ????????。 注明:本篇博客不会涉及容器的源码什么的,主要是总结各个map容器的底层实现特点、主要运用场景。如果你需要详细了解更多关于Java中的map容器实现的细节,文末会提供我前面写的源码分析的博客链接,欢迎阅读。 Java中的常见五种map容器源码分析总结目录一、`Java`中...

hestyle的博客 1657

理解HashMap的负载系数

初始容量和负载系数决定了HashMap什么时候扩容。假如初始容量为C,负载系数为1,那么当给Map加入了C+1个元素之后才会扩容。我们分析加入C个元素时的状态。最理想的情况是每个hashCode位置都有一个元素。但是显然这种情况是很难发生的,绝大多数情况在实际大小等于容量的时候,都已经发生了哈希冲突了。HashMap发生哈希冲突的处理策略是,当同一位置的节点数小于8的话,会使用链表结构。链表结构就导致了取元素的时候时间复杂度为O(n),超过八个就会用红黑树结构来存储节点,红黑树的查询复杂度也是logn,和O

qq_43556545的博客 676

基于STM32与FPGA Cyclone IV的FSMC高速数据通信实战解析

本文详细解析了基于STM32的FSMC接口与FPGA Cyclone IV实现高速并行数据通信的实战方案。通过将FPGA模拟为SRAM设备,构建了MCU与FPGA之间的高速数据通道,并深入探讨了硬件连接、STM32软件配置、FPGA逻辑设计及性能优化等关键步骤,为图像处理、高速采集等需要大数据量交换的嵌入式应用提供了稳定高效的通信解决方案。

swift5iosmith的博客 294

【Java源码分析】Java8的HashMap源码分析

Java8中的HashMap源码分析 源码分析 HashMap的定义 字段属性 hash函数 comparableClassFor,compareComparables函数 tableSizeFor函数tableSizeFor函数 putMapEntries,putAll函数putMapEntries,putAll函数 size,isEmpty函数size,isEmpty函数 contai...

长路漫漫的歇脚处 2748

银行卡密码键盘 SM4 ECB模式+ANSI X9.8 格式标准(带主账号信息)PIN 加解密示例

文章目录1.软加解密示例2.知识点①ANSI X9.8 格式标准②主密钥,工作密钥加解密基本概念:加密种类:3.密码键盘操作4.工具 1.软加解密示例 ————————————————————————————————————————————------ 已知数据: 银行测试主密钥TMK: 1234567890ABCDEFABCDEF0987654321 通过签到接口得到: 工作密钥密文KeyVal...

老孟嘚吧嘚 6651

Delphi开发者必备:CEF4Delphi跨平台浏览器嵌入实战指南(含Lazarus适配)

本文详细介绍了Delphi开发者如何利用CEF4Delphi实现跨平台浏览器嵌入,包括环境配置、Lazarus适配、ARM架构优化及Firemonkey集成等实战技巧。通过Chromium引擎的强大功能,开发者可以轻松为传统桌面应用添加现代浏览器特性,提升多平台开发效率。

weixin_29233333的博客 226

Java集合源码分析(五)——HashMap

简介 HashMap 是一个散列表,存储的内容是键值对映射。 HashMap 继承于AbstractMap,实现了Map、Cloneable、java.io.Serializable接口。 HashMap 存储的键值对是无序的。 源码分析 public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable {} 实现接口 Map Clon

Think Different. 257

基于STM32L4XX、HAL库的RTL8201F 以太网收发器(PHY)驱动程序设计

define PHY_RESET_DELAY 1000 // PHY复位延迟(ms)#define PHY_AUTONEGO_DELAY 3000 // 自动协商延迟(ms)/* 检查PHY ID (RTL8201F的ID为0x001CC816) *//* 系统时钟配置,确保ETH有50MHz时钟 *//* 初始化CPU, AHB和APB总线时钟 */

zhusl6688的博客 803

JAVA 8 HashMap 源码分析

HashMap 继承了AbstractMap,实现了Map接口,HashMap是根据key-value来存储数据的,HashMap其实就是一个数组+链表+红黑树组成的。因为HashMap在存储数据的时候,会先去计算key的hash值,因为一个相同的key值,所得的hash值应该是唯一的,所以我们可以很快的去定位到value的值。HashMap允许key和value都为null,但是key只能有一次为空。HashMap是非线程安全的,所以非常不建议在多线程中去操作hashMap,以为这样会导致数据不统一。

LOSER_zcy的博客 647

FANUC机器人_KAREL编程入门学习(1)

FANUC机器人_KAREL编程入门学习(1)

Robot_PLC_HMI_Automation 6419

OpenClaw 实战:7个真实场景的多 Agent 落地经验

《OpenClaw实战:7个真实场景的多Agent落地经验》摘要: 作者Maynor分享了从单Agent转向多Agent架构的实战经验。最初遇到的单Agent记忆混乱问题(如Flutter助手被C++话题干扰),通过拆分专项Agent(flutter-tutor/cpp-tutor等)并配置独立workspace解决。随后面临的技能调用混乱问题,采用"基础通用能力+专属能力"分层策略,通过Clawhub管理工具市场,将工具调用准确率从60%提升至95%。最后探讨多Agent协同方案,引入

Maynor的博客 1411

java hashmap原ma_hashmap源码分析( 基于java8)

hashmap源码分析简介hashmap的get和put操作的时间复杂度是常量。通过调用哈希函数将元素正确的分布到桶中。初始容量(capacity)的值不能设置太高,加载因子(loadfactor)不能设置的太低,否则会影响迭代的性能。一个hashmap的实例有两个参数将影响它的性能。初始容量、加载因子。初始容量是hashmap在创建时候桶的大小。加载因子用来确定何时进行扩容(size > ...

weixin_35712036的博客 115

华为OD机考真题 新系统 - 数列求值(Java/Py/C/C++/Js/Go)

华为OD机试真题 新系统【数列求值】,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解,以及在线OJ模拟做题。华为OD机试真题 【数列求值】多语言题解。

qq_45776114的博客 662

Java HashMap源码分析

转自:Snailclimb 文章链接:https://github.com/Snailclimb/JavaGuide/blob/master/Java%E7%9B%B8%E5%85%B3/HashMap.md HashMap 简介 HashMap 主要用来存放键值对,它基于哈希表的Map接口实现,是常用的Java集合之一。 JDK1.8 之前 HashMap 由 数组+链表 组成的,数...

xiaoman0743的博客 544

Django框架中settings文件的部署建议

为了更好地管理开发和生产环境的配置,建议将settings文件分为多个文件,分别用于不同的环境。然后,通过在启动应用程序时指定不同的settings文件,来加载相应的配置。在Django框架中,settings.py文件是非常重要的配置文件,它包含了项目的各种设置和选项。在Django框架中,settings.py文件是非常重要的配置文件,它包含了项目的各种设置和选项。可以使用Python的。为了更好地管理开发和生产环境的配置,建议将settings文件分为多个文件,分别用于不同的环境。

WELL_CODER的博客 128

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

java HashMap 源码分析(深度讲解)

java 集合篇章——HashMap源码分析(非常详细)。

优快云 / 稀土掘金/ B站 / GitHub: Cyan_RA9 2559

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

【Java 基础】HashMap 的底层原理和源码分析

HashMap 内部维护了一个数组,称为哈希表,每个元素都是一个链表的头结点,该链表被称为桶(bucket)。当我们向 HashMap 中添加一个元素时,首先会根据该元素的键值(key)计算出一个哈希值(hash code),然后根据哈希值确定该元素在数组中的位置,如果该位置上已经存在了元素,则将该元素添加到该位置上对应的桶中,如果该位置上没有元素,则创建一个新的桶,并将该元素添加到该桶中

激流丶的博客 2501

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

【Java集合篇】jdk8的HashMap源码分析

文章目录前言:Java7的HashMap链接:一.HashMap底层是怎么存储的?Entry是什么?1.Node是什么(JDK7中的Entry)?2.默认大小:3.为什么Java8的HashMap是数组+链表+红黑树?二、构造器1.调用无参构造器,底层table实例化了吗?2.调用有参构造器,底层table实例化了吗?3.总结三、put方法:底层数组的实例化,就在这里啊!!!!1.调用无参构造器后,第一次调用put方法2.何时采用红黑树?四.jdk8中的几个重要的常量五.jdk7到jdk8为什么要进行修改?

好吃的爆米花 600

Java学习笔记——HashMap底层源码分析

目录源码内一些参数介绍实例化(声明一个HashMap对象)注意事项添加键值对hash(key)源码分析putVaule()源码分析resize()源码分析扩容后重新计算键值对在数组中的位置JDK1.7与JDK1.8的区别插入值put扩容resize() 源码内一些参数介绍 capacity:HashMap的容量,即Node[]数组的size,HashMap会强制的将容量设置为2的幂,这样在对key取hash值的时候可以直接使用位运算来计算hash值。(比如容量为16时,只取key对象hash值的后4位,

qq_36334929的博客 3076

Java数据集合---HashMap源码分析

在Java面试中,关于Java数据集合的相关面试题中,HashMap的出现频率还是非常高的。所以写下了本篇文章,第一个目的是为了通过自己的源码阅读,加深对HashMap的结构的印象,学习HashMap的设计思路。第二个目的就是记录自己学习的过程,整理HashMap的相关问题,为后续面试做准备。注意:本次源码分析使用的是JDK1.8 版。

qq_34561305的博客 935

Java集合之HashMap源码分析

阅读目录 一、HashMap简介二、hashMap源码分析三、HashMap的应用示例代码四、HashMap总结 回到顶部 一、HashMap简介   HashMap是基于哈希表的Map接口实现的,它存储的是内容是键值对映射。此类不保证映射的顺序,假定哈希函数将元素适当的分布在各桶之间,可为基本操作(get和put)提供稳定的性能。   ps:本文中的源码来自jd

qianyiyiding的专栏 311

hashmap源码分析( 基于java8)

hashmap源码分析 简介 hashmap的get和put操作的时间复杂度是常量。通过调用哈希函数将元素正确的分布到桶中。初始容量(capacity)的值不能设置太高,加载因子(loadfactor)不能设置的太低,否则会影响迭代的性能。一个hashmap的实例有两个参数将影响它的性能。初始容量、加载因子。初始容量是hashmap在创建...

weixin_34416649的博客 118

Java集合源码分析(四)HashMap

Java集合源码分析(四)HashMap 阅读目录(Content) 一、HashMap简介 1.1、HashMap概述 1.2、HashMap在JDK1.8以前数据结构和存储原理 1.3、JDK1.8后HashMap的数据结构 1.4、HashMap的属性 二、HashMap的源码分析(一) 2.1、HashMap的层次关系与继承结构 2.2、Has...

weixin_30247307的博客 90

[Java] HashMap源码分析

版权声明:请尊重个人劳动成果,转载注明出处,谢谢!http://blog.youkuaiyun.com/amazing7/article/details/51283211 目录(?)[+] 1.概述   Hashmap继承于AbstractMap,实现了Map、Cloneable、Java.io.Serializable接口。它的key、value...

weixin_33939380的博客 94

Java集合-HashMap源码分析

Java的HashMap是一种基于哈希表实现的数据结构,用于存储键值对。在HashMap中,每个键都映射到一个值。

重生之我是cxk的博客 331
上一篇: [Java]String类分析源码阅读
下一篇: [Java]ThreadPoolExecutor源码分析
HeapStackk
博客等级 码龄12年 11粉丝 58原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值