今天复习了一下HashMap的部分,写一篇博客记录一下今天学习内容

虽然之前学习过,但由于后来没怎么使用过而且也没复习基本忘得差不多了

在Java的HashMap中,高效存储键值对的核心在于哈希算法和索引定位。本文将结合源码逐步拆解存储流程,并给出代码示例。

 核心流程概述
  1. 扰动函数处理Key 通过扰动函数优化Key的哈希值,减少碰撞
  2. 存储哈希值 计算后的哈希值存入Node对象的hash字段
  3. 计算桶下标 用(n-1) & hash定位数组索引(n为数组长度)
  4. 存入数据结构 根据下标存入数组(或链表/红黑树)
 源码级分步解析(基于JDK 17)
① 扰动函数与哈希计算
static final int hash(Object key) {int h;return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}

  • 作用:将原始哈希码的高16位与低16位异或
  • 目的:让高位参与运算,解决低位相同导致的哈希碰撞
  • 结果:扰动后的哈希值存储在Node的hash字段
② Node对象结构
static class Node<K,V> implements Map.Entry<K,V> {final int hash; // 存储扰动计算后的哈希值final K key;V value;Node<K,V> next; // 链表结构指针
}

③ 索引定位公式
// 在putVal方法中:
int index = (n - 1) & hash;
  • n-1:当前数组长度减1(如长度16→15,二进制0...01111
  • 位与运算:高效实现取模运算,hash % n等价于(n-1) & hash
    ④ 完整put流程伪代码
    final V putVal(int hash, K key, V value) {Node<K,V>[] tab; Node<K,V> p; int n, i;// 1. 首次使用触发初始化if ((tab = table) == null || (n = tab.length) == 0)n = (tab = resize()).length;// 2. 计算桶下标 (核心公式)i = (n - 1) & hash;// 3. 处理碰撞情况if ((p = tab[i]) == null) tab[i] = newNode(hash, key, value); // 无碰撞直接存else {// 碰撞后遍历链表/红黑树if (p.hash == hash && ...)// 更新已存在key的值else {// 链表新增节点if (binCount >= TREEIFY_THRESHOLD - 1)treeifyBin(tab, hash); // 链表转红黑树}}
    }

    举个🌰 实战示例与验证
    import java.util.*;public class HashMapDemo {public static void main(String[] args) {HashMap<String, Integer> map = new HashMap<>(16); // 初始容量16// 存储键值对 "A":1map.put("A", 1);// 手动验证存储过程String key = "A";// 1. 原始哈希码int hashCode = key.hashCode(); System.out.println("原始哈希码: 0x" + Integer.toHexString(hashCode));// 2. 扰动计算int perturbedHash = hash(key);System.out.println("扰动哈希值: 0x" + Integer.toHexString(perturbedHash));// 3. 计算桶下标 (n=16)int n = 16;int index = (n - 1) & perturbedHash;System.out.println("数组下标: " + index);}// JDK扰动函数实现static int hash(Object key) {int h;return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);}
    }

    输出结果

    原始哈希码: 0x41
    扰动哈希值: 0x41  // 小值无高位变化
    数组下标: 1       // (16-1)=15: 0b1111 & 0x41=65 → 1
     设计原理深度剖析
    1. 为什么用位与代替取模?

      • 位运算(n-1) & hash%效率高10倍以上(实测)
      • 前提:数组长度必须是2的幂(保证n-1的二进制全为1)
    2. 扰动函数的必要性

       原始哈希: 0x1234abcd 和 0x5678abcdn=16时:未扰动 → 两值低位相同 → 碰撞扰动后 → 高位参与运算 → 低位不同 → 避免碰撞

         3.哈希碰撞策略

    最佳实践建议
    1. 避免自定义Key哈希碰撞
       // 错误实现:所有对象返回相同哈希码@Overridepublic int hashCode() { return 1; } // 导致HashMap退化为链表// 正确实现:组合关键字段哈希@Overridepublic int hashCode() {return Objects.hash(field1, field2);}

    1. 初始化容量优化
       // 预期存储1000个元素时new HashMap<>(2048); // 避免扩容 (1000/0.75≈1333 → 取2的幂2048)

    至此,本章的内容结束,后续我会补充一下在高并发情况下HashMap会出现的一些问题    

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

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

        相关文章

        【机器学习 / 深度学习】基础教程

        阶段一&#xff1a;机器学习 / 深度学习基础教程定位&#xff1a;针对准备进入 AI多智能体开发 的初学者&#xff0c;打牢机器学习与深度学习的基础。一、为什么需要学习机器学习/深度学习 在进入智能体&#xff08;Agent&#xff09;开发之前&#xff0c;必须具备一定的 机器学…

        ESP32应用——HTTP client(ESP-IDF框架)

        目录 一、前言 二、URL 2.1 URL简介 2.2 URL示例 三、HTTP 3.1 HTTP协议概述 3.2 HTTP的工作原理 3.2.1 HTTP 请求-响应流程 3.2.2 HTTP 请求结构 3.2.3 HTTP请求方法 3.2.4 HTTP响应结构 3.2.5 HTTP状态码 四、ESP HTTP 客户端流程 五、ESP HTTP 客户端实战解析…

        动学学深度学习07-现代卷积神经网络

        动学学深度学习pytorch 参考地址&#xff1a;https://zh.d2l.ai/ 文章目录动学学深度学习pytorch1-第07章-现代卷积神经网络1. AlexNet1.1 AlexNet 的核心贡献是什么&#xff1f;1.2 AlexNet 与 LeNet 的主要区别有哪些&#xff1f;1.3 为什么 AlexNet 需要 GPU 训练&#xff1…

        详细讲解Java中的反射和经典面试题(保姆级别)

        1.1 反射的概述&#xff1a;专业的解释&#xff08;了解一下&#xff09;&#xff1a;是在运行状态中&#xff0c;对于任意一个类&#xff0c;都能够知道这个类的所有属性和方法&#xff1b;对于任意一个对象&#xff0c;都能够调用它的任意属性和方法&#xff1b;这种动态获取…

        MyCAT完整实验报告

        MyCAT完整实验报告 ‍ 前言 刚刚看了一下前面的那篇MyCAT的文章 感觉有一些问题 所以拿出一篇文章再说一下 单独构建了完整的实验环境 这样会全面一点 ‍ 安装MyCAT #跳过‍ 主从配置 #不多追溯 因为我们选择的主从 也可以做双主机 但我们后边再说‍ 环境搭建 一、环境规划 服务…

        机器翻译论文阅读方法:顶会(ACL、EMNLP)论文解析技巧

        更多内容请见: 机器翻译修炼-专栏介绍和目录 文章目录 一、论文选择:快速判断论文价值 1.1 关注核心会议与子领域 1.2 筛选标准 1.3 预读筛选 1.4 快速定位关键信息 二、精读解析 2.1 问题定义(5分钟) 2.2 方法解剖(15分钟) 2.3 实验深挖(20分钟) 2.4 批判性思考(10分…

        Transformer模型实战篇

        引入 基于Transformers的NLP解决方案的步骤如下&#xff1a;&#xff08;以文本分类为例&#xff09; 导入相关包&#xff0c;General&#xff0c;可以询问ai需要导什么包加载数据集&#xff0c;Data_loader&#xff0c;Datasets数据集划分&#xff0c;测试机&#xff0c;验证集…

        深入(流批【牛批】框架)Flink的机制

        flink本身是专注有状态的无限流处理&#xff0c;有限流处理【batch批次】是无限流处理的一中特殊情况&#xff01;应用场景实时ETL 集成流计算现有的诸多数据通道和SQL灵活的加工能力&#xff0c;对流式数据进行实时清洗、归并和结构化 处理&#xff1b;同时&#xff0c;对离线…

        Git 2.15.0 64位安装步骤Windows详细教程从下载到验证(附安装包下载)

        一、下载后双击运行 安装包下载&#xff1a;https://pan.quark.cn/s/7200b32a1ecf&#xff0c;找到下载好的文件&#xff1a;​Git-2.15.0-64-bit.exe​双击这个文件&#xff0c;就会弹出安装向导窗口&#xff0c;点 ​​“Next”&#xff08;下一步&#xff09;​​ 二、选择…

        在职老D渗透日记day23:sqli-labs靶场通关(第29关-31关)http参数过滤

        5.29.第29关 http参数过滤 闭合5.29.1.手动注入&#xff08;1&#xff09;判断注入类型、注入点闭合&#xff08;2&#xff09;有回显&#xff0c;优先用联合查询注入&#xff0c;判读字段数?id1&id2 order by 3 -- ?id1&id2 order by 4 --&#xff08;3&#xff09;…

        Spring Boot整合Amazon SNS实战:邮件订阅通知系统开发

        Spring Boot整合Amazon SNS实战引言配置服务总结新用户可获得高达 200 美元的服务抵扣金 亚马逊云科技新用户可以免费使用亚马逊云科技免费套餐&#xff08;Amazon Free Tier&#xff09;。注册即可获得 100 美元的服务抵扣金&#xff0c;在探索关键亚马逊云科技服务时可以再额…

        LeetCode_动态规划1

        动态规划1.动态规划总结1.1 01背1.1.1 二维数组1.1.2 一维数组1.2 完全背包2.斐波那契数(力扣509)3.爬楼梯(力扣70)4.使用最小花费爬楼梯(力扣746)5.不同路径(力扣62)6.不同路径 II(力扣63)7.整数拆分(力扣343)8.不同的二叉搜索树(力扣96)9.分割等和子集(力扣416)10.最后一块石…

        【STM32】HAL库中的实现(九):SPI(串行外设接口)

        SPI 接口通信原理 SPI&#xff08;Serial Peripheral Interface&#xff09;是全双工主从通信协议&#xff0c;特点是&#xff1a; 信号线功能SCK串行时钟MOSI主设备输出&#xff0c;从设备输入MISO主设备输入&#xff0c;从设备输出CS&#xff08;NSS&#xff09;片选信号&am…

        Git常用操作大全(附git操作命令)

        Git常用操作大全 一、基础配置 1.1 设置用户名和邮箱 git config --global user.name "你的名字" git config --global user.email "你的邮箱"1.2 查看配置 git config --list二、仓库管理 2.1 初始化本地仓库 git init2.2 克隆远程仓库 git clone <仓库…

        详解flink table api基础(三)

        文章目录1.使用flink的原因&#xff1a;2. Flink支持两种模式&#xff1a;3. flink table api工作原理&#xff1a;4. Flink table api 使用5. select语句&flink table api&#xff1a;6. 使用flink table api 创建table7. 使用flink table api 写流式数据输出到表或sink8.…

        Vue2+Vue3前端开发_Day5

        参考课程: 【黑马程序员 Vue2Vue3基础入门到实战项目】 [https://www.bilibili.com/video/BV1HV4y1a7n4] ZZHow(ZZHow1024) 自定义指令 基本语法&#xff08;全局 & 局部注册&#xff09; 介绍&#xff1a;自己定义的指令&#xff0c;可以封装一些 DOM 操作&#xff0c…

        机器学习--决策树2

        目录 第一代裁判&#xff1a;ID3 与信息增益的 “偏爱” 第二代裁判&#xff1a;C4.5 用 “增益率” 找平衡 第三代裁判&#xff1a;CART 的 “基尼指数” 新思路 遇到连续值&#xff1f;先 “砍几刀” 再说 给决策树 “减肥”&#xff1a;剪枝的学问 动手试试&#xff1…

        yggjs_react使用教程 v0.1.1

        yggjs_react是一个用于快速创建React项目的工具&#xff0c;它集成了Vite、TypeScript、Zustand和React Router等现代前端技术栈&#xff0c;帮助开发者快速搭建高质量的React应用。 快速入门 快速入门部分将指导您如何安装yggjs_react工具、创建新项目并启动开发服务器。 安…

        vulhub可用的docker源

        这一块不太容易找&#xff0c;我试了好几个源&#xff0c;下面是20250820测试可用源 编辑方法sudo mkdir -p /etc/docker sudo vim /etc/docker/daemon.json 配置内容 [1] {"registry-mirrors" : ["https://docker.registry.cyou", "https://docker-…

        基于YOLOv8-SEAttention与LLMs融合的农作物害虫智能诊断与防控决策系统

        1. 引言 1.1 研究背景与意义 农作物虫害是制约农业产量与质量的重要因素。据FAO报告&#xff0c;全球每年因病虫害造成的粮食损失高达 20%–40%。传统人工巡查与经验诊断具有时效性差、成本高与专业人才不足等缺陷。近年来&#xff0c;计算机视觉特别是目标检测技术在农业检测…