当前位置: 首页 > news >正文

Golang | HashMap实现原理

在这里插入图片描述
在这里插入图片描述

  • HashMap是一种基于哈希表实现的键值对存储结构,它通过哈希函数将键映射到数组的索引位置,支持高效的插入、查找和删除操作。其核心原理如下:
    • 哈希函数:将键转换为数组索引。理想情况下,不同键应映射到不同索引,但冲突难以避免。
    • 数组+链表:使用数组作为桶(Bucket),每个桶是一个链表,解决哈希冲突(链地址法)。
    • 动态扩容:当元素数量超过容量与负载因子的乘积时,扩容并重新分配元素,保持操作高效性。
package mainimport "fmt"// Entry 键值对链表节点
type Entry struct {Key   stringValue interface{}Next  *Entry
}// HashMap 哈希表结构
type HashMap struct {buckets    []*Entry // 桶数组capacity   int      // 初始容量size       int      // 元素数量loadFactor float64  // 负载因子
}// NewHashMap 初始化哈希表
func NewHashMap(capacity int) *HashMap {return &HashMap{buckets:    make([]*Entry, capacity),capacity:   capacity,loadFactor: 0.75,}
}// hash 哈希函数(FNV-1a算法)
func (h *HashMap) hash(key string) int {const (offset = 2166136261prime  = 16777619)hash := offsetfor _, c := range key {hash ^= int(c)hash *= prime}return hash
}// getIndex 计算键对应的桶索引
func (h *HashMap) getIndex(key string) int {return h.hash(key) % h.capacity
}// Put 插入键值对
func (h *HashMap) Put(key string, value interface{}) {if float64(h.size)/float64(h.capacity) >= h.loadFactor {h.resize()}index := h.getIndex(key)entry := h.buckets[index]// 遍历链表查找键是否存在for entry != nil {if entry.Key == key {entry.Value = value // 存在则更新return}entry = entry.Next}// 不存在则插入链表头部h.buckets[index] = &Entry{Key:   key,Value: value,Next:  h.buckets[index],}h.size++
}// Get 获取值
func (h *HashMap) Get(key string) (interface{}, bool) {index := h.getIndex(key)entry := h.buckets[index]for entry != nil {if entry.Key == key {return entry.Value, true}entry = entry.Next}return nil, false
}// Delete 删除键
func (h *HashMap) Delete(key string) bool {index := h.getIndex(key)entry := h.buckets[index]var prev *Entryfor entry != nil {if entry.Key == key {if prev == nil {h.buckets[index] = entry.Next // 删除头节点} else {prev.Next = entry.Next // 中间或尾部节点}h.size--return true}prev = entryentry = entry.Next}return false
}// resize 扩容哈希表
func (h *HashMap) resize() {newCapacity := h.capacity * 2newBuckets := make([]*Entry, newCapacity)for i := 0; i < h.capacity; i++ {entry := h.buckets[i]for entry != nil {next := entry.NextnewIndex := h.hash(entry.Key) % newCapacity // 重新计算索引entry.Next = newBuckets[newIndex]          // 插入新桶头部newBuckets[newIndex] = entryentry = next}}h.buckets = newBucketsh.capacity = newCapacity
}func main() {hm := NewHashMap(2) // 初始容量设为2便于触发扩容hm.Put("name", "Alice")hm.Put("age", 30)hm.Put("lang", "Go") // 触发扩容if val, ok := hm.Get("name"); ok {fmt.Println("name:", val) // 输出 Alice}hm.Delete("age")if _, ok := hm.Get("age"); !ok {fmt.Println("age deleted") // 输出此句}
}

相关文章:

  • electron-builder 打包安装与启动手动安装,最终解决方案,之前的文章与其他的人都不用看了。
  • 面向对象编程核心:封装、继承、多态与 static 关键字深度解析
  • 使用 uv 工具快速创建 MCP 服务(Trae 配置并调用 MCP 服务)
  • 百度Create2025 AI开发者大会:模型与应用的未来已来
  • 【HTTP/2和HTTP/3的应用现状:看不见的革命】
  • Linux驱动开发快速上手指南:从理论到实战
  • 大内存生产环境tomcat-jvm配置实践
  • 常见网络安全攻击类型深度剖析(四):跨站脚本攻击(XSS)——分类、漏洞利用与前端安全防护
  • 《100天精通Python——基础篇 2025 第3天:变量与数据类型全面解析,掌握Python核心语法》
  • Ubuntu 下 Nginx 1.28.0 源码编译安装与 systemd 管理全流程指南
  • Java大师成长计划之第3天:Java中的异常处理机制
  • 第3讲:ggplot2完美入门与美化细节打磨——从基础绘制到专业级润色
  • 华为OD机试真题——查找接口成功率最优时间段(2025A卷:100分)Java/python/JavaScript/C/C++/GO最佳实现
  • oracle数据库物理结构
  • 【Pandas】pandas DataFrame radd
  • HMI与组态,自动化的“灵珠”和“魔丸”
  • 2.5 桥梁桥面系及附属结构施工
  • 【Langchain】RAG 优化:提高语义完整性、向量相关性、召回率--从字符分割到语义分块 (SemanticChunker)
  • 【含文档+PPT+源码】基于微信小程序的校园快递平台
  • 语音合成之五语音合成中的“一对多”问题主流模型解决方案分析
  • 单位被裁定补缴12年社保,滞纳金该谁出?
  • 泰山景区管委会:未经审核同意不得擅自举办竞速类登山活动
  • 双拥主题歌曲MV:爱我人民,爱我军
  • 全国首个古文学习AI大模型在沪发布,可批阅古文翻译
  • 习近平同肯尼亚总统鲁托会谈
  • 北京顺义:做好潮白河大桥事故善后处置,举一反三排查风险