【Go语言基础【18】】Map基础

文章目录

  • 零、概述
  • 一、Map基础
    • 1、Map的基本概念与特性
    • 2、Map的声明与初始化
    • 3、Map的基本操作
  • 二、Map的底层实现
  • 三、Map的注意事项

零、概述

Map与其他语言的对比

特性Go mapJava HashMapPython dict
并发安全非线程安全,需手动加锁非线程安全(ConcurrentHashMap线程安全)非线程安全
遍历顺序无序无序(LinkedHashMap有序)插入顺序(Python 3.7+)
键类型限制必须可比较必须实现hashCodeequals必须可哈希(hashable)
自动扩容支持支持支持

使用时需注意:

  • 初始化后才能使用,避免操作nil map。
  • 键必须为可比较类型,值可以是任意类型。
  • 非并发安全,并发场景需额外保护。
  • 遍历顺序不确定,如需有序遍历可先排序键。

 

一、Map基础

1、Map的基本概念与特性

1.本质

map是一种引用类型,底层实现为哈希表(hash table)。通过哈希函数将键(key)映射到值(value),实现快速存取。

2.核心特性

  • 无序性:元素的存储顺序不确定,遍历时不保证顺序。
  • 键唯一性:键不能重复,重复插入会覆盖原有值。
  • 键类型限制:键必须是可比较类型(如整数、字符串、指针、结构体等),因为需要通过==判断键是否存在。
  • 动态扩容:随着元素增加,会自动扩容以保持性能。

在这里插入图片描述

 

2、Map的声明与初始化

1.声明未初始化的map(nil map)

var m map[string]int // nil map,不可直接使用
// m["key"] = 100  // 错误:nil map不能赋值

2.使用make初始化map

m := make(map[string]int)        // 创建空map
m := make(map[string]int, 10)    // 预分配容量(优化性能)

3.使用字面量初始化

m := map[string]int{"apple":  1,"banana": 2,
}

 

3、Map的基本操作

存取元素

m := make(map[string]int)
m["apple"] = 100       // 插入/更新元素
value := m["apple"]    // 获取元素

检查键是否存在

value, exists := m["apple"]
if exists {fmt.Println("键存在,值为:", value)
} else {fmt.Println("键不存在")
}

删除元素

delete(m, "apple")     // 删除键,无论键是否存在都不会报错

遍历Map

 for key, value := range m {fmt.Println(key, value)}// 只遍历键for key := range m {fmt.Println(key)}

 

二、Map的底层实现

Go的map底层使用哈希表实现,核心结构是hmap(hash map):

// A header for a Go map.
type hmap struct {// 元素个数,调用 len(map) 时,直接返回此值count     intflags     uint8// buckets 的对数 log_2B         uint8// overflow 的 bucket 近似数noverflow uint16// 计算 key 的哈希的时候会传入哈希函数hash0     uint32// 指向 buckets 数组,大小为 2^B// 如果元素个数为0,就为 nilbuckets    unsafe.Pointer// 扩容的时候,buckets 长度会是 oldbuckets 的两倍oldbuckets unsafe.Pointer// 指示扩容进度,小于此地址的 buckets 迁移完成nevacuate  uintptrextra *mapextra // optional fields
}

核心组件

  1. 桶(bucket) : 每个桶最多存储8个键值对,超出时通过溢出桶(overflow bucket)链接。

  2. 哈希函数 : 将键转换为哈希值,低几位用于定位桶,高8位用于快速比较键

  3. 扩容机制 : 当装载因子(元素数/桶数)超过6.5或溢出桶过多时,触发扩容:

    • 翻倍扩容:创建新桶数组,大小为原数组的2倍,渐进式迁移元素。
    • 等量扩容:重新排列桶内元素,使存储更紧凑(解决溢出桶过多问题)。

该结构中用于存储key value的数据结构是 buckets([]bmap), 其中bmap就是我们常说的“桶”,桶里面最多装 8 个元素(key-value)

如果有第 9 个 元素 落入当前的 bucket,那就需要再构建一个 bucket ,通过 overflow 指针连接起来。
在这里插入图片描述

 

Map的性能特点

  1. 时间复杂度
    • 插入、查找、删除:平均为O(1),最坏为O(n)(极端哈希冲突)。
    • 遍历:O(n)。
  2. 性能优化
    • 预分配容量:若已知元素数量,使用make(map[T]T, size)减少扩容次数。
    • 避免大结构体作为键:使用指针或基础类型作为键,减少哈希计算开销。

 

三、Map的注意事项

1.并发安全
map不是并发安全的,多个goroutine同时读写会导致panic。需使用sync.Map或加锁。

import "sync"var m sync.Map
m.Store("key", "value")
value, ok := m.Load("key")

2.nil map与空map

  • nil map:未初始化,不可读写,需用make或字面量初始化。
  • 空map:已初始化但无元素,可以读写。

3.键类型限制
键必须是可比较类型(如intstringstruct中字段均为可比较类型),不可使用切片、map、函数等不可比较类型。

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

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

相关文章

Qt客户端技巧 -- 窗口美化 -- 窗口阴影

不解析&#xff0c;直接给示例 窗口设为不边框且背景透明,好用来承载阴影 窗口一个Widget用来作真实窗口的作用&#xff0c;在真实窗口上加上阴影特效 上下两层Widget方式 main.cpp #include <QtCore/qglobal.h> #if QT_VERSION > 0x050000 #include <QtWidget…

优选算法第十二讲:队列 + 宽搜 优先级队列

优选算法第十二讲&#xff1a;队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…

华为OD最新机试真题-流水线-OD统一考试(B卷)

题目描述: 有个工厂有m条 流水线,来并行完成n个独立的作业,该工厂设置了一个调度系统,在安排作业时,总是优先执行处理时间最短的作业。 现给定流水线个数m,需要完成的作业数n,每个作业的处理时间分别为t1,.2..n。请你编程计算处理完所有作业的耗时为多少? 当n>m时

区块链技术概述

区块链技术是一种去中心化、分布式账本技术&#xff0c;通过密码学、共识机制和智能合约等核心组件&#xff0c;实现数据不可篡改、透明可追溯的系统。 一、核心技术 1. 去中心化 特点&#xff1a;数据存储在网络中的多个节点&#xff08;计算机&#xff09;&#xff0c;而非…

项目css / js的兼容性next项目实践处理

之前写过一篇&#xff0c;但是没有css的处理&#xff0c;但是那一篇有几个文章蛮好的https://blog.csdn.net/SaRAku/article/details/144704916 css兼容性和js兼容性 1. 确定需要兼容的版本 先确定你们的兼容性版本&#xff0c;我们的兼容性以APP H5的兼容版本为最低兼容性&…

Vue3 + Vite 中使用 Lodash-es 的防抖 debounce 详解

Vue3 Vite 中使用 Lodash-es 的防抖(debounce)详解 在 Vue3 Vite 项目中&#xff0c;debounce 是 lodash-es 中最常用的功能之一&#xff0c;它可以帮助我们优化高频事件的处理。下面我将详细讲解 debounce 的使用方法&#xff0c;并提供一个完整的示例。 Debounce 核心概念…

MySQL--慢查询日志、日志分析工具mysqldumpslow

mysqldumpslow 常用参数&#xff1a; -s&#xff0c;是order的顺序----- al 平均锁定时间-----ar 平均返回记录时间-----at 平均查询时间&#xff08;默认&#xff09;-----c 计数-----l 锁定时间-----r 返回记录-----t 查询时间-t&#xff0c;是top n的意思&#xff0c;即为返…

C++课设:实现图书馆借阅记录系统(支持书籍管理、借阅功能、超期检测提醒)

名人说&#xff1a;路漫漫其修远兮&#xff0c;吾将上下而求索。—— 屈原《离骚》 创作者&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 专栏介绍&#xff1a;《编程项目实战》 目录 一、系统概述与设计思路1. 系统核心功能…

矩阵和向量范数的区别分析

文章目录 1. 研究对象本质差异2. 运算和作用方式不同3. 应用需求不同4. 数学性质和理论体系不同5. 几何直观不同6. 范数定义区别7. 范数计算方式区别8. 范数几何意义区别9. 范数相容性区别总结 1. 研究对象本质差异 向量本质&#xff1a;向量是具有大小和方向的一维有序数组&a…

HTMLCSS 学习总结

目录 ​​​一、HTML核心概念​​ ​​三大前端技术作用​​ ​​HTML基础结构​​ 开发工具&#xff1a;VS Code 专业配置​​​​安装步骤​​&#xff1a; ​​二、HTML标签大全&#xff08;含表格&#xff09;​​ ​​三、CSS核心技术​​ 1. 三种引入方式对比 2.…

Java + Spring Boot + Mybatis 实现批量插入

在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法&#xff1a;使用 MyBatis 的 <foreach> 标签和批处理模式&#xff08;ExecutorType.BATCH&#xff09;。 方法一&#xff1a;使用 XML 的 <foreach> 标签&#xff…

Oracle11g安装包

Oracle 11g安装包 适用于windows系统&#xff0c;64位 下载路径 oracle 11g 安装包

通过Cline使用智能体

文章目录 1、VS Code配置2、Cline使用2.1 工作模式2.2 MCP服务2.3 Cline支持的服务 3、案例一&#xff1a;天气查询项目3.1 需求说明3.2 申请高德API Key3.3 实操&#xff1a;向Cline下达命令 4、案例二&#xff1a;双城天气对比项目4.1 需求说明4.2 实操 Cline是VS Code的插件…

「混合开发」H5与原生App交互流程方案全面解析

目录 内嵌H5调用iOS内的方法 1. 背景 2. 解决方案 2.1 创建WebView 2.2 注册原生方法 2.3 H5调用原生方法 3. 序列图 H5 调用 Android&#xff1a;详细指南 整体流程 每一步的详细说明 步骤1&#xff1a;在Android项目中设置WebView 步骤2&#xff1a;定义JavaScri…

webpack打包vue项目

要在 Vue 项目中使用 Webpack 进行打包&#xff0c;通常有几种不同的方式来设置你的项目。以下是基本步骤&#xff1a; 1. 使用 Vue CLI 创建项目&#xff08;推荐&#xff09; Vue CLI 是官方提供的一个脚手架工具&#xff0c;它内置了对 Webpack 的支持&#xff0c;并且简化…

Linux环境-通过命令查看zookeeper注册的服务

假设前置条件如下&#xff1a; 1.root权限用户名&#xff1a;zookeeper 2.zookeeper所在服务器地址&#xff1a;168.7.3.254&#xff08;非真实ip&#xff09; 3.zookeeper的bin文件路径&#xff1a;/opt/zookeeper/bin 4.确保zookeeper注册中心已启动 查看注册中心服务如下&a…

BLEU评分:机器翻译质量评估的黄金标准

BLEU评分&#xff1a;机器翻译质量评估的黄金标准 1. 引言 在自然语言处理(NLP)领域&#xff0c;衡量一个机器翻译模型的性能至关重要。BLEU (Bilingual Evaluation Understudy) 作为一种自动化评估指标&#xff0c;自2002年由IBM的Kishore Papineni等人提出以来&#xff0c;…

ArcGIS计算多个栅格数据的平均栅格

3种方法计算多个栅格数据的平均栅格 1->使用“ 栅格计算器”工具 原理就是把多幅影像数据相加&#xff0c;然后除以个数&#xff0c;就能得到平均栅格。 2-> 使用“像元统计数据”工具&#xff0c;如果是ArcGIS pro&#xff0c;则是“像元统计”工具。使用这个工具可以…

Ubantu-Docker配置最新镜像源250605

尝试其他镜像加速器 阿里云镜像加速器&#xff1a;登录阿里云&#xff0c;进入容器镜像服务获取专属加速器地址。毫秒镜像&#xff1a;https://docker.1ms.run。DockerHub镜像加速器&#xff1a;https://docker.xuanyuan.me。Docker Hub 镜像加速服务&#xff1a;https://dock…

中医有效性探讨

文章目录 西医是如何发展到以生物化学为药理基础的现代医学&#xff1f;传统医学奠基期&#xff08;远古 - 17 世纪&#xff09;近代医学转型期&#xff08;17 世纪 - 19 世纪末&#xff09;​现代医学成熟期&#xff08;20世纪至今&#xff09; 中医的源远流长和一脉相承远古至…