Java集合学习:HashMap的原理
一、HashMap里的Hash是什么?
首先,我们先要搞清楚HashMap里的的Hash是啥意思。
当我们在编程过程中,往往需要对线性表进行查找操作。
在顺序表中查找时,需要从表头开始,依次遍历比较a[i]与key的值是否相等,直到相等才返回索引i;在有序表中查找时,我们经常使用的是二分查找,通过比较key与a[i]的大小来折半查找,直到相等时才返回索引i。最终通过索引找到我们要找的元素。
但是,这两种方法的效率都依赖于查找中比较的次数。
那能不能不经过比较,而是直接通过关键字key一次得到所要的结果呢?这时,就有了散列表查找(哈希表)
散列技术是指在记录的存储位置和它的关键字之间建立一个确定的对应关系f,使每一个关键字都对应一个存储位置。这样,在查找的过程中,只需要通过这个对应关系f 找到给定值key的映射f(key)。只要集合中存在关键字和key相等的记录,则必在存储位置f(key)处。我们把这种对应关系f 称为散列函数或哈希函数。按照这个思想,采用散列技术将记录存储在一块连续的存储空间中,这块连续的存储空间称为哈希表。所得的存储地址称为哈希地址或散列地址。
相信看到这里大家都懂这个Hash是什么意思了,其实就是散列技术,通过一个对应关系快速找到目标值的位置。
二、HashMap是什么?
HashMap是正是基于哈希表的数据结构,用于存储键值对(key-value)。
HashMap基于键的HashCode值唯一标识一条数据,同时基于键的HashCode值进行数据的存取,因此可以快速地更新和查询数据,但其每次遍历的顺序无法保证相同。
HashMap的key和value允许为null。
HashMap是非线程安全的,即在同一时刻有多个线程同时写HashMap时将可能导致数据的不一致。
如果需要满足线程安全的条件,则可以用Collections的synchronizedMap方法使HashMap具有线程安全的能力,或者使用ConcurrentHashMap。
三、HashMap的底层原理
HashMap的核心原理是将键的哈希值映射到数组索引位置,通过数组+链表(在Java 8及之后是数组+链表或红黑树)来处理哈希冲突。
HashMap使用键的hashCode()方法计算哈希值,并通过indexFor方法(JDK1.7之后版本移除了这个方法,直接使用(n-1) & hash)确定元素在数组中的存储位置。哈希值是经过一定扰动处理的,防止哈希值分布不均匀,从而减少哈希冲突。
1、HashMap的数据结构
HashMap的数据结构如上图所示,其内部是一个数组,数组中的每个元素都是一个单向链表,链表中的每个元素都是嵌套类Entry的实例,Entry实例包含4个属性:key、value、hash值和用于指向单向链表下一个元素的next。
HashMap在查找数据时,根据HashMap的Hash值可以快速定位到数组的具体下标,但是在找到数组下标后需要对链表进行顺序遍历直到找到需要的数据,时间复杂度为O(n)。为了减少链表遍历的开销,Java 8对HashMap进行了优化,将数据结构修改为数组+链表或红黑树。在链表中的元素超过8个以后,HashMap会将链表结构转换为红黑树结构以提高查询效率,红黑树是一种自平衡二叉搜索树,能够将最坏情况下的查询复杂度从O(n)降低到O(log N)。如果树中元素的数量低于6个,红黑树会转换回链表,以减少不必要的树操作开销。
Java 8 HashMap的数据结构如下图所示:
2、hashCode()和equals()的重要性
HashMap的键必须实现hashCode()和equals()方法。hashCode()用于计算哈希值,以决定键的存储位置,而equals()用于比较两个键是否相同。在put操作时,如果两个键的hashCode()相同,但equals()返回false,则这两个键会被视为不同的键,存储在同一个桶的不同位置。
误用hashCode()和equals()会导致HashMap中的元素无法正常查找或插入
3、默认容量与负载因子的选择
HashMap常用的参数如下:
- capacity:当前数组的容量,默认为16,可以扩容,扩容后数组的大小为当前的两倍,因此该值始终为2n。
- loadFactor:负载因子,默认为0.75。
- threshold:扩容的阈值,其值等于capacity×loadFactor。
默认容量是16,负载因子是0.75,这个组合是在性能和空间之间找到平衡。较高的负载因子会减少空间浪费,但增加了哈希冲突的概率;较低的负载因子会增加空间开销,但减少哈希冲突。
如果已知HashMap的容量需求,建议提前设定合适的初始容量,以减少扩容带来的性能损耗。
4、哈希冲突链表法
当要塞入一个键值对的时候,会根据一个hash算法计算key的hash值,然后通过数组大小n-1 & hash值之后,得到一个数组的下标,然后往那个位置塞入这个键值对
hash算法是可能产生冲突的,且数组的大小是有限的,所以很可能通过不同的key计算得到一样的下标,因此为了解决键值对冲突的问题,采用了链表法:
在JDK1.7及之前链表的插入采用的是头插法,即每当发生哈希冲突时,新的节点总是插入到链表的头部,老节点依次向后移动,形成新的链表结构。
多线程的情况下,头插法可能会导致链表形成环,特别是在并发扩容时。
在JDK1.8的时候,改成了尾插法,即新节点插入到链表的尾部,保持插入的顺序。
相关文章:
Java集合学习:HashMap的原理
一、HashMap里的Hash是什么? 首先,我们先要搞清楚HashMap里的的Hash是啥意思。 当我们在编程过程中,往往需要对线性表进行查找操作。 在顺序表中查找时,需要从表头开始,依次遍历比较a[i]与key的值是否相等ÿ…...
使用rsync+inotify简单实现文件实时双机双向同步
使用rsyncinotify简单实现文件实时双机双向同步 实现思路 使用inotify-tools的inotifywait工具监控文件变化,触发后使用rsync做同步。加入系统服务项,实现实时监听,方便管理。 以下配置操作,单向同步,只需在单边部…...
[JavaScript] ES6及以后版本的新特性
文章目录 箭头函数(Arrow Functions)为什么需要箭头函数?箭头函数的完整语法箭头函数中的 this实用场景 解构赋值(Destructuring Assignment)为什么需要解构赋值?数组解构赋值的完整用法对象解构赋值的完整…...
IO进程 寒假作业
一、请使用消息队列实现2个终端之间互相聊天 #include <stdio.h> #include <stdlib.h> #include <signal.h> #include <sys/wait.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> …...
无公网IP 外网访问媒体服务器 Emby
Emby 是一款多媒体服务器软件,用户可以在 Emby 创建自己的个人多媒体娱乐中心,并且可以跨多个设备访问自己的媒体库。它允许用户管理传输自己的媒体内容,比如电影、电视节目、音乐和照片等。 本文将详细的介绍如何利用 Docker 在本地部署 Emb…...
【2025小年源码免费送】
💖学习知识需费心, 📕整理归纳更费神。 🎉源码免费人人喜, 🔥码农福利等你领! 💖山高路远坑又深, 📕大军纵横任驰奔, 🎉谁敢横刀立马行…...
哈希表示例
示例1 两数之和 "两数之和"(Two Sum)是LeetCode上的一个经典算法问题,编号为1,它要求在一个整数数组nums中找到两个不同的索引i和j,使得nums[i] nums[j] target。 问题描述: 给定一个整数数…...
VS企业版和专业版的区别
网上查询vs分析dump文件,查找托管内存泄露,需要使用“调试托管内存”功能,当前安装的vs2022 专用版找不到这个选项,vs2015是ok的,比较版本发现2022是专业版,2015是企业版。网上搜索专业版和企业版差异如下&…...
YOLOv10-1.1部分代码阅读笔记-train.py
train.py ultralytics\models\yolov10\train.py 目录 train.py 1.所需的库和模块 2.class YOLOv10DetectionTrainer(DetectionTrainer): 1.所需的库和模块 from ultralytics.models.yolo.detect import DetectionTrainer from .val import YOLOv10DetectionValidator fr…...
autogen 自定义agent (1)
目录 第一个自定义agent:CountDownAgent代码运行逻辑1. 创建 CountDownAgent 代理2. 处理消息3. 运行 CountDownAgent 另一种调用方式类似的agent: CountUpAgent 第一个自定义agent:CountDownAgent from typing import AsyncGenerator, List, Sequence,…...
ssh密钥登录GitHub时一直提示“Error: Permission denied (publickey)”
起因 环境:Windows10 背景:之前就是按照官方说明创建个rsa密钥,在git后台添加上,就行了,近期怎么添加怎么失败,总是“Error: Permission denied (publickey)”的提示! 尝试 各种尝试…...
多模态数据融合的基本流程与关键环节
多模态数据融合作为人工智能的重要技术方向,不仅整合了视觉、语言、语音、传感器等多种模态的数据,还通过合理的融合方法让机器获得更全面的感知能力。那么,多模态数据融合的过程是怎样的?有哪些关键环节需要注意?今天…...
k8s 蓝绿发布、滚动发布、灰度发布
在Kubernetes(k8s)中,蓝绿发布、滚动发布、灰度发布(金丝雀发布)是三种常见的应用部署和更新策略。下面将分别对这几种发布方式进行说明,并给出相应的例子。 蓝绿发布 蓝绿发布是一种无缝切换版本的部署策…...
【PyCharm】连接Jupyter Notebook
【PyCharm】相关链接 【PyCharm】连接 Git【PyCharm】连接Jupyter Notebook【PyCharm】快捷键使用【PyCharm】远程连接Linux服务器【PyCharm】设置为中文界面 【PyCharm】连接Jupyter Notebook PyCharm连接Jupyter Notebook的过程可以根据不同的需求分为 本地连接 和 远程连…...
【miniconda】:langraph的windows构建
langraph需要python3.11 langraph强烈建议使用py3.11 默认是3.12 官方 下载仓库 下载老版本的python (后续发现新版miniconda也能安装老版本的python) 在这里...
NRF52840 USB Dongle 进行蓝牙抓包
1、可视化抓包 官方的工具 链接:RF Connect for Desktop ,之后使用 bluetooth Low Energy 即可查看抓包数据。不做说明。 本节主要说明,使用wireshark进行抓包数据的显示。 1.1、硬件 Nordic Semiconductor 官网链接 的截图如下。国内封装…...
【C++】详细讲解继承(下)
本篇来继续说说继承。上篇可移步至【C】详细讲解继承(上) 1.继承与友元 友元关系不能继承 ,也就是说基类友元不能访问派⽣类私有和保护成员。 class Student;//前置声明class Same //基类 { public:friend void Fun(const Same& p, con…...
OS Copilot功能测评:智能助手的炫彩魔法
简介: OS Copilot 是一款融合了人工智能技术的智能助手,专为Linux系统设计,旨在提升系统管理和运维效率。本文详细介绍了在阿里云ECS实例上安装和体验OS Copilot的过程,重点评测了其三个核心参数:-t(模式…...
Gin 学习笔记
教程地址:https://www.bilibili.com/video/BV1FV4y1C72M?spm_id_from333.788.videopod.sections&vd_source707ec8983cc32e6e065d5496a7f79ee6 01-项目搭建 各常用目录的说明: https://github.com/golang-standards/project-layout/blob/master/REA…...
windows在命令行中切换盘符
一、问题描述 我们在使用windows的cmd(命令行)时,经常需要用cd命令在不同盘之间切换路径。但有时在不同盘之间切换时,会发现命令不起作用。 如下图所示,直接切换目录还是停留在原来的位置。 二、解决方法 首先切换盘符…...
OpenAI模块重构
文章目录 1.common-openai-starter1.目录结构2.OpenAiProperties.java 新增apiUrl3.OpenAIAutoConfiguration.java4.OpenAiClient.java 使用gson重构 2.common-openai-starter-demo1.目录结构2.application.yml 新增api-url3.OpenAiController.java4.OpenAiApplication.java5.测…...
表的增删改查(MySQL)
1. 表的增删改查 CRUD : Create(创建), Retrieve(读取),Update(更新),Delete(删除) 1.1 Create 语法: INSERT [INTO] table_name [(column [, column] ...)] VALUES (value_list) [, (value_list)] ...value_list:…...
Go 不可重复协程安全队列
代码实现 package dataStructimport ("errors""sync" )// GenericQueue 是一个支持泛型的不可重复队列,具有最大长度限制 // T 是泛型参数 type GenericQueue[T comparable] struct {items map[T]struct{} // 使用 map 来存储元素order []…...
每日一题 419. 棋盘上的战舰
419. 棋盘上的战舰 简单 class Solution { public:int countBattleships(vector<vector<char>>& board) {int ans 0;for(int i0;i<board.size();i){for(int j0;j<board[0].size();j){if(board[i][j] X){dfs(board,i,j);ans;}}}return ans;}void dfs(…...
spring cloud alibaba 使用示例
spring cloud alibaba example spring cloud alibaba nacos 配置中心、spring cloud alibaba nacos 服务注册与发现、openfeign 服务调用、spring cloud loadbalancer 负载均衡、spring cloud alibaba sentinel 限流降级、spring cloud alibaba seata 分布式事务、spring clou…...
Python数据分析-Python语法基础,IPython和Jupyter-Notebooks(二)
title: ‘Python数据分析:Python语法基础,IPython和Jupyter Notebooks(二)’ tags: python数据分析 categories:python数据分析 keywords:python数据分析 cover: …/img/404_icecream_whale.png description: 本文介绍python的基础语法和jup…...
领域驱动设计(DDD)Spring Boot 3 实现 二
使用 Spring Boot 3 实现领域驱动设计(DDD)是一种很自然的选择,因为 Spring 提供了良好的生态支持,特别是在分层架构、依赖管理、事件驱动等方面。以下是如何在 Spring Boot 3 中结合 DDD 进行开发的详细指南: 项目结构…...
Vue.js 高级组件开发
Vue.js 高级组件开发:构建一个智能动态表单生成器 ——从可复用架构到性能优化的全链路实践 引言:为什么需要高级组件? 在现代前端开发中,组件不仅是UI的封装,更是业务逻辑的载体。一个“高级”Vue组件应当具备&…...
wangEditor富文本编辑器,Laravel上传图片配置和使用
文章目录 前言步骤1. 构造好前端模版2. 搭建后端存储3. 调试 前言 由于最近写项目需要使用富文本编辑器,使用的是VUE3.0版本所以很多不兼容,实际测试以后推荐使用wangEditor 步骤 构造好前端模版搭建后端存储调试 1. 构造好前端模版 安装模版 模版安…...
Hive之加载csv格式数据到hive
场景: 今天接了一个需求,将测试环境的hive数据导入到正式环境中。但是不需要整个流程的迁移,只需要迁移ads表 解决方案: 拿到这个需求首先想到两个方案: 1、将数据通过insert into语句导出,然后运行脚本 …...
0164__【GNU】gcc -O编译选项 -Og -O0 -O1 -O2 -O3 -Os
【GNU】gcc -O编译选项 -Og -O0 -O1 -O2 -O3 -Os_gcc -o0-CSDN博客...
《DiffIR:用于图像修复的高效扩散模型》学习笔记
paper:2303.09472 GitHub:GitHub - Zj-BinXia/DiffIR: This project is the official implementation of Diffir: Efficient diffusion model for image restoration, ICCV2023 目录 摘要 1、介绍 2、相关工作 2.1 图像恢复(Image Rest…...
[Datawheel]利用Zigent框架编写智能体-2
书接上回 1. Zigent实现教程编写智能体 本节将通过 Zigent 框架实现一个教程编写智能体,其主要功能是输入教程主题,然后自动生成完整的教程内容。 设计思路: 先通过 LLM 大模型生成教程的目录,再对目录按照二级标题进行分块&…...
cursor重构谷粒商城05——docker容器化技术快速入门【番外篇】
前言:这个系列将使用最前沿的cursor作为辅助编程工具,来快速开发一些基础的编程项目。目的是为了在真实项目中,帮助初级程序员快速进阶,以最快的速度,效率,快速进阶到中高阶程序员。 本项目将基于谷粒商城…...
Django项目的创建及运行——Django学习日志(一)
1.命令行创建 (1)创建项目 django-admin startproject HelloWorld(这里的名称任意) (2)创建应用(app) 首先要进入到项目目录,比如我这里的项目目录为HelloWorld cd …...
gesp(C++六级)(1)洛谷:P10250:[GESP样题 六级] 下楼梯
gesp(C六级)(1)洛谷:P10250:[GESP样题 六级] 下楼梯 题目描述 顽皮的小明发现,下楼梯时每步可以走 1 1 1 个台阶、 2 2 2 个台阶或 3 3 3 个台阶。现在一共有 N N N 个台阶,你能帮小明算算有多少种方案…...
1.23学习
misc buuctf-小明的保险箱 打开附件是一个在线图片首先将其另存为,然后仅仅只是一个图片,而无其他信息,那么我们再进行binwalk或者foremost文件分离,得到了一个文件夹,其中含有一个压缩包但是是一个加密的࿰…...
atheris从安装到fuzz输入输出解读
1. 引入 模糊测试是一种自动化的软件测试技术,它通过自动生成大量随机数据作为输入来测试程序,以发现潜在的错误、漏洞或崩溃。atheris是一个专门用于CPython(Python的C语言实现)的模糊测试框架。 2. 安装atheris 参考1&#x…...
基于自然语言处理的垃圾短信识别系统
基于自然语言处理的垃圾短信识别系统 🌟 嗨,我是LucianaiB! 🌍 总有人间一两风,填我十万八千梦。 🚀 路漫漫其修远兮,吾将上下而求索。 目录 设计题目设计目的设计任务描述设计要求输入和输出…...
PAT甲级-1022 Digital Libiary
题目 题目大意 一个图书有图书id,书名,作者,关键字,出版商,出版时间6个信息。现要查询图书的ID,1对应通过书名查询,2对应作者,3对应关键字(不需要完全一致,包…...
GD32F470 USB虚拟串口
1. 硬件连接 确保GD32F470开发板的USB接口连接到PC的USB端口。开发板通常提供USB FS(全速)接口,可以直接使用。 2. 配置USB功能 需要配置USB时钟、GPIO和中断,以支持全速USB设备模式。 2.1 配置USB时钟 c复制 void usb_rcu_…...
25美赛ABCDEF题详细建模过程+可视化图表+参考论文+写作模版+数据预处理
详情见该链接!!!!!! 25美国大学生数学建模如何准备!!!!!-CSDN博客文章浏览阅读791次,点赞13次,收藏7次。通过了解比赛基本…...
【转帖】eclipse-24-09版本后,怎么还原原来版本的搜索功能
【1】原贴地址:eclipse - 怎么还原原来版本的搜索功能_eclipse打开类型搜索类功能失效-CSDN博客 https://blog.csdn.net/sinat_32238399/article/details/145113105 【2】原文如下: 更新eclipse-24-09版本后之后,新的搜索功能(CT…...
Elasticsearch 性能测试工具 Loadgen 之 002——命令行及参数详解
上一讲,我们讲解了 Loadgen 的极简部署方式、配置文件、快速使用从 0 到 1 方式。 本讲,我们主要解读一下 Loadgen 的丰富的命令行及参数含义。 有同学可能会说,上面不是介绍很清楚了吗?但,咱们还是有必要详细中文解读…...
DRG/DIP 2.0时代下基于PostgreSQL的成本管理实践与探索(下)
五、数据处理与 ETL 流程编程实现 5.1 数据抽取与转换(ETL) 在 DRG/DIP 2.0 时代的医院成本管理中,数据抽取与转换(ETL)是将医院各个业务系统中的原始数据转化为可供成本管理分析使用的关键环节。这一过程涉及从医院 HIS 系统中抽取患者诊疗数据,并对其进行格式转换、字…...
【设计模式-行为型】状态模式
一、什么是状态模式 什么是状态模式呢,这里我举一个例子来说明,在自动挡汽车中,挡位的切换是根据驾驶条件(如车速、油门踏板位置、刹车状态等)自动完成的。这种自动切换挡位的过程可以很好地用状态模式来描述。状态模式…...
想品客老师的第六天:函数
函数基础的部分写在这里 函数声明 在js里万物皆对象,函数也可以用对象的方式定义 let func new Function("title", "console.log(title)");func(我是参数title); 也可以对函数赋值: let cms function (title) {console.log(tit…...
hedfs和hive数据迁移后校验脚本
先谈论校验方法,本人腾讯云大数据工程师。 1、hdfs的校验 这个通常就是distcp校验,hdfs通过distcp迁移到另一个集群,怎么校验你的对不对。 有人会说,默认会有校验CRC校验。我们关闭了,为什么关闭?全量迁…...
面向通感一体化的非均匀感知信号设计
文章目录 1 非均匀信号设计的背景分析1.1 基于OFDM波形的感知信号1.2 非均匀信号设计的必要性和可行性1.2 非均匀信号设计的必要性和可行性 3 通感一体化系统中的非均匀信号设计方法3.1 非均匀信号的设计流程(1)均匀感知信号设计(2࿰…...
React将props传递给一个组件
React 组件通讯:从单向数据流到跨层级交互的深度实践 ——基于 Props 的通讯机制解析与高阶模式探索 一、Props 的本质:不可变数据管道 React 的 props(properties)机制构建了单向数据流的核心范式。每个父组件通过 props 向子…...