Java-HashMap中put()方法是如何实现的,内含详细流程图

文章目录

  • Java中的HashMap
    • 什么是HashMap?
    • 对比其他Map中put()方法
    • HashMap中put()方法使用示例
  • HashMap中put()源码解析
    • 手绘流程图
    • 实现原理
    • 源码探究(JDK 1.8)
  • 设计put()的意义
  • 总结

Java中的HashMap

什么是HashMap?

HashMap是Java中常用的数据结构之一,它基于哈希表实现,提供了快速的键值对存取能力。在HashMap中,put方法是最常用的方法之一,用于将键值对存储到HashMap中。本文将深入探究HashMap的put方法的实现原理,解析其内部数据结构和算法,并探讨设计put方法的意义。

对比其他Map中put()方法

可以看一下博主的博客了解HashMap、TreeMap和LinkedHashMap三者的使用:Java-数据结构(二)-Map:HashMap、TreeMap、LinkedHashMap
HashMap、TreeMap和LinkedHashMap都是Java中常用的Map实现类,它们在put方法的实现上有一些区别。

  1. HashMap的put方法:

    • HashMap使用哈希表来存储键值对,通过键的哈希码和哈希函数来确定键值对在哈希表中的存储位置。
    • 当发生哈希冲突时,HashMap使用链表或红黑树来解决冲突。
    • HashMap的put方法具有O(1)的平均时间复杂度。
  2. TreeMap的put方法:

    • TreeMap使用红黑树来存储键值对,根据键的自然顺序或自定义比较器来进行排序。
    • 在插入键值对时,TreeMap会根据键的顺序将键值对插入到相应的位置,以保持有序性。
    • TreeMap的put方法具有O(log n)的时间复杂度。
  3. LinkedHashMap的put方法:

    • LinkedHashMap继承自HashMap,底层仍然使用哈希表来存储键值对。
    • LinkedHashMap在HashMap的基础上,使用双向链表来维护键值对的插入顺序或访问顺序。
    • 在插入键值对时,LinkedHashMap会将键值对插入到链表的尾部,以保持插入顺序或访问顺序。
    • LinkedHashMap的put方法具有O(1)的平均时间复杂度。
  • HashMap的put方法使用哈希表来存储键值对,适用于需要高效存储和查找键值对的场景。
  • TreeMap的put方法使用红黑树来存储键值对,适用于需要有序存储和查找键值对的场景。
  • LinkedHashMap的put方法在HashMap的基础上,使用双向链表来维护插入顺序或访问顺序,适用于需要保持插入顺序或访问顺序的场景。

HashMap中put()方法使用示例

以下是一个简单的Java代码示例,展示了如何使用HashMap的put方法:

import java.util.HashMap;public class HashMapExample {public static void main(String[] args) {// 创建一个HashMap对象HashMap<String, Integer> hashMap = new HashMap<>();// 使用put方法添加键值对hashMap.put("apple", 1);hashMap.put("banana", 2);hashMap.put("cherry", 3);// 使用get方法获取键对应的值int value = hashMap.get("banana");System.out.println("The value of 'banana' is: " + value);}
}

HashMap中put()源码解析

手绘流程图

在这里插入图片描述

实现原理

在Java中,HashMap的put方法的实现原理可以分为以下几个步骤:

1.首先,根据键的哈希值计算出键的哈希码。HashMap使用键的哈希码来确定键值对在哈希表中的存储位置。

2.接下来,通过哈希码计算出键值对在哈希表中的索引位置。HashMap使用一个称为“哈希函数”的算法来计算索引位置。常用的哈希函数是将哈希码与哈希表的容量进行取模运算,得到索引位置。

3.如果该索引位置上没有其他键值对,则直接将键值对存储在该位置上。如果该索引位置上已经存在其他键值对,则发生了“哈希冲突”。

4.当发生哈希冲突时,HashMap使用链表或红黑树来解决冲突。在JDK1.8之前,HashMap使用链表来解决冲突,即在冲突的索引位置上,将新的键值对插入到链表的尾部。而在JDK1.8及以后的版本中,当链表长度超过一定阈值时,HashMap会将链表转换为红黑树,以提高查找效率。

5.最后,将键值对成功存储在哈希表中,并返回先前关联的值(如果存在)。如果该索引位置上已经存在其他键值对,则需要遍历链表或红黑树,找到对应的键值对,并更新其值。

通过以上步骤,HashMap的put方法成功将键值对存储在哈希表中。需要注意的是,当哈希表的负载因子(即存储的键值对数量与容量的比值)超过一定阈值时,HashMap会进行扩容操作,以保持哈希表的性能。

源码探究(JDK 1.8)

public V put(K key, V value) {return putVal(hash(key), key, value, false, true);
}final V putVal(int hash, K key, V value, boolean onlyIfAbsent,boolean evict) {Node<K,V>[] tab; Node<K,V> p; int n, i;// table未初始化或者长度为0,进行扩容if ((tab = table) == null || (n = tab.length) == 0)n = (tab = resize()).length;// (n - 1) & hash 确定元素存放在哪个桶中,桶为空,新生成结点放入桶中(此时,这个结点是放在数组中)if ((p = tab[i = (n - 1) & hash]) == null)tab[i] = newNode(hash, key, value, null);// 桶中已经存在元素(处理hash冲突)else {Node<K,V> e; K k;//快速判断第一个节点table[i]的key是否与插入的key一样,若相同就直接使用插入的值p替换掉旧的值e。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);// 结点数量达到阈值(默认为 8 ),执行 treeifyBin 方法// 这个方法会根据 HashMap 数组来决定是否转换为红黑树。// 只有当数组长度大于或者等于 64 的情况下,才会执行转换红黑树操作,以减少搜索时间。否则,就是只是对数组扩容。if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1sttreeifyBin(tab, hash);// 跳出循环break;}// 判断链表中结点的key值与插入的元素的key值是否相等if (e.hash == hash &&((k = e.key) == key || (key != null && key.equals(k))))// 相等,跳出循环break;// 用于遍历桶中的链表,与前面的e = p.next组合,可以遍历链表p = e;}}// 表示在桶中找到key值、hash值与插入元素相等的结点if (e != null) {// 记录e的valueV oldValue = e.value;// onlyIfAbsent为false或者旧值为nullif (!onlyIfAbsent || oldValue == null)//用新值替换旧值e.value = value;// 访问后回调afterNodeAccess(e);// 返回旧值return oldValue;}}// 结构性修改++modCount;// 实际大小大于阈值则扩容if (++size > threshold)resize();// 插入后回调afterNodeInsertion(evict);return null;
}

设计put()的意义

设计put方法的意义在于提供了一种简单而高效的方式来存储和查找键值对。HashMap的put方法具有O(1)的平均时间复杂度,即使在发生哈希冲突的情况下,通过链表或红黑树的处理,也能保持较快的查找性能。这使得HashMap成为了处理大量数据的理想选择,尤其在需要频繁进行键值对操作的场景下。

总结

本文深入探究了Java中HashMap的put方法的实现原理。通过了解其内部数据结构和算法,我们可以更好地理解和使用HashMap,在实际开发中更加高效地进行键值对的存储和查找操作。同时,我们也探讨了设计put方法的意义,以及提供了相关的Java代码示例。希望本文对读者有所帮助,让大家对HashMap的put方法有更深入的理解。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/72265.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

羊城杯2023 部分wp

目录 D0nt pl4y g4m3!!!(php7.4.21源码泄露&pop链构造) Serpent(pickle反序列化&python提权) ArkNights(环境变量泄露) Ez_misc(win10sinpping_tools恢复) D0nt pl4y g4m3!!!(php7.4.21源码泄露&pop链构造) 访问/p0p.php 跳转到了游戏界面 应该是存在302跳转…

1783_CMD启动MATLAB同时执行一个脚本

全部学习汇总&#xff1a; GitHub - GreyZhang/g_matlab: MATLAB once used to be my daily tool. After many years when I go back and read my old learning notes I felt maybe I still need it in the future. So, start this repo to keep some of my old learning notes…

ELK框架Logstash配合Filebeats和kafka使用

ELK框架Logstash配合Filebeats和kafka使用 本文目录 ELK框架Logstash配合Filebeats和kafka使用配置文件结构input为标准输入&#xff0c;output为标准输出input为log文件output为标准输出output为es input为tcpspringboot配置logstash配置 input为filebeatsfilebeats配置logsta…

Matlab论文插图绘制模板第111期—带线标记的图

本期分享的是带线标记注释的图。 先来看一下成品效果&#xff1a; 特别提示&#xff1a;本期内容『数据代码』已上传资源群中&#xff0c;加群的朋友请自行下载。有需要的朋友可以关注同名公号【阿昆的科研日常】&#xff0c;后台回复关键词【绘图桶】查看加入方式。 模板中最…

Android 网络配置

adb root adb shell 改变网卡网址 ifconfig eth0 192.168.0.167 up 添加虚拟网卡 ifconfig eth0:0 192.168.10.10 up 以上的命令就可以在eth0网卡上创建一个叫eth0:0的虚拟网卡,他的地址是:192.168.10.10 删除虚拟网卡 ifconfig eth0:0 down ip route 查看路由表的内容 …

【数据结构】如何设计循环队列?图文解析(LeetCode)

LeetCode链接&#xff1a;622. 设计循环队列 - 力扣&#xff08;LeetCode&#xff09; 目录 做题思路 只开辟 k 个空间 多开一个空间 代码实现 1. 循环队列的结构 2. 开辟空间 3. 判断空 4. 判断满 5. 队尾插入数据 6. 队头删除数据 7. 获取队头元素 8. 获取队尾元…

炫酷的开关--20230907

Night && Day Toggle ☀️/&#x1f319; [Completed It!] HTML&#xff1a; <div class"controls"><label for"sync">Sync <body></label><input id"sync" type"checkbox"/> </div> &l…

基于javaweb的网上图书销售系统(servlet+jsp)

系统简介 本项目采用eclipse工具开发&#xff0c;jspservletjquery技术编写&#xff0c;数据库采用的是mysql&#xff0c;navicat开发工具。 角色&#xff1a; 管理员普通用户 模块简介 管理员&#xff1a; 登录用户管理图书分类管理图书管理图书订单管理图书评论管理数据统…

【通俗理解】CNN卷积神经网络 - 附带场景举例

一. CNN 算法概述 CNN的全称是Convolutional Neural Networks, ConvNets&#xff0c;称之为卷积神经网络&#xff0c;是深度学习的经典算法之一。 CNN一般用于图片分类、检索、人脸识别、目标定位等。在常规的图像处理的过程中&#xff0c;存在以下两个问题&#xff1a; 图像…

【2023高教社杯】D题 圈养湖羊的空间利用率 问题分析、数学模型及MATLAB代码

【2023高教社杯】D题 圈养湖羊的空间利用率 问题分析、数学模型及MATLAB代码 1 题目 题目 D 题 圈养湖羊的空间利用率 规模化的圈养养殖场通常根据牲畜的性别和生长阶段分群饲养&#xff0c;适应不同种类、不同阶段的牲畜对空间的不同要求&#xff0c;以保障牲畜安全和健康&a…

离线数仓同步数据3

业务数据_增量表数据同步 1&#xff09;Flume配置概述2&#xff09;Flume配置实操3&#xff09;通道测试4&#xff09;编写Flume启停脚本 1&#xff09;Flume配置概述 Flume需要将Kafka中topic_db主题的数据传输到HDFS&#xff0c;故其需选用KafkaSource以及HDFSSink&#xff…

内网穿透实现Windows远程桌面访问Ubuntu,简单高效的远程桌面解决方案

文章目录 前言1. ubuntu安装XRDP2.局域网测试连接3.安装cpolar内网穿透4.cpolar公网地址测试访问5.固定域名公网地址 前言 XRDP是一种开源工具&#xff0c;它允许用户通过Windows RDP访问Linux远程桌面。 除了Windows RDP外&#xff0c;xrdp工具还接受来自其他RDP客户端(如Fre…

uni-app 之 uni.request 网络请求API接口

uni-app 之 uni.request 网络请求API接口 image.png <template><!-- vue2的<template>里必须要有一个盒子&#xff0c;不能有两个&#xff0c;这里的盒子就是 view--><view>--- uni.request 网络请求API接口 ---<view><!-- 免费的测试接口 --…

制造企业如何优化物料控制?

导 读 ( 文/ 2127 ) 物料控制是指对制造过程中所涉及的物料流动和库存进行有效管理和控制的过程。它包括物料需求计划、供应商管理、物料采购、物料接收和入库、物料库存管理以及物料发放和使用等关键环节。通过精确的物料需求计划和库存管理&#xff0c;物料控制可以确保物料供…

转载: 又拍云【PrismCDN 】低延时的P2P HLS直播技术实践

低延时的P2P HLS直播技术实践本文是第二部分《PrismCDN 网络的架构解析,以及低延迟、低成本的奥秘》低延时的P2P HLS直播技术实践 [首页 > Open Talk NO.41 | 2018 音视频技术沙龙深圳站 > 低延时 WebP2P 直播技术实践https://opentalk-blog.b0.upaiyun.com/prod/2018-0…

【群答疑】jmeter关联获取上一个请求返回的字符串,分割后保存到数组,把数组元素依次作为下一个请求的入参...

一个非常不错的问题&#xff0c;来检验下自己jmeter基本功 可能有同学没看懂题&#xff0c;这里再解释一下&#xff0c;上面问题需求是&#xff1a;jmeter关联获取上一个请求返回的字符串&#xff0c;分割后保存到数组&#xff0c;把数组元素依次作为下一个请求的入参 建议先自…

TCP流量控制和拥塞控制,具体在场景中是怎么起作用的

TCP的流量控制 所谓的流量控制就是让发送方的发送速率不要太快&#xff0c;让接收方来得及接受。利用滑动窗口机制可以很方便的在TCP连接上实现对发送方的流量控制。TCP的窗口单位是字节&#xff0c;不是报文段&#xff0c;发送方的发送窗口不能超过接收方给出的接收窗口的数值…

《TCP/IP网络编程》阅读笔记--域名及网络地址

目录 1--域名系统 2--域名与 IP 地址的转换 2-1--利用域名来获取 IP 地址 2-2--利用 IP 地址获取域名 3--代码实例 3-1--gethostbyname() 3-2--gethostbyaddr() 1--域名系统 域名系统&#xff08;Domain Name System&#xff0c;DNS&#xff09;是对 IP 地址和域名进行相…

OLED透明屏模块:引领未来显示技术的突破

OLED透明屏模块作为一项引领未来显示技术的突破&#xff0c;以其独特的特点和卓越的画质在市场上引起了广泛关注。 根据行业报告&#xff0c;预计到2025年&#xff0c;OLED透明屏模块将占据智能手机市场的20%份额&#xff0c;并在汽车导航系统市场中占据30%以上份额。 那么&am…

安装K8s基础环境软件(二)

所有节点执行 1、安装docker sudo yum install -y yum-utils sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.reposudo yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin systemctl…