首页 > 其他分享 >golang中map基础了解

golang中map基础了解

时间:2022-10-04 21:44:18浏览次数:50  
标签:key map hash string golang 了解 哈希 data

map初识

map是一个以键值对元素的数据集合,map是一个集合。

map的优点是查找速度非常会,原因是map的底层存储是hash表。

hash表的存储原理:

对key进行计算,计算出hash值,对hash值进行取模,通过取模得到索引。

这种模式快的原因就是可以根据key直接寻找到数据存放的位置,不需要前后逐一对比。

如果取模后索引相等就是hash冲突,解决hash冲突的方法有

  • 开放地址法

  • 拉链法

map扩容:通过扩容扩大索引值的范围,减少hash冲突的概率

map的特点

  • 键不能重复
  • 键必须可以算出hash值,可hash的有int、float、string、bool、array这些数据类型(slice不能用作键)
  • 无序

map的声明与初始化

//声明一个map并初始化两个值
userInfo := map[string]string{"name":"张三","age":="18"}
//map修改值
userInfo["age"] = "20"
//map新增值
userInfo["email"]="[email protected]"

使用make进行初识化

//也可以写data := make(map[int]int,10),初始化10个位置放置数据,通常不写
data := make(map[int]int)
data[100] = 998
data[200] = 999

上面两种是最常见的,还有两种不常见的

//这种声明,因为没有初始化,所以键的值为nil,不能具体赋值,只能整体赋值
var row map[string]int
//将data这个map整体赋值给row
row = data
//new返回的是指针,内部也是nil,这种声明也是用于整体赋值,但是赋值要转成指针在赋值
value := new(map[string]int)

value = &data

map常用操作

长度和容量

data := map[string]string("n1":"123","n2":"222")
value := len(data) //2
//容量初始化10,根据给的参数值10,map会计算出一个合适的容量,
//map中包含很多桶,每个桶中可以存8个键值对
info := make(map[string]string,10)
info["n1"] = "111"
info["n2"] = "1111"

v1 := len(info)//2,获取的是键值对的个数而不是容量的大小

增删改查

//添加
data := map[string]string("n1":"123","n2":"222")
data["n3"] = "1"
//修改
data["n1"] = "·12345"
//删除
delete(data,"n2")
//查看
for key,value := range data{
    fmt.Println(key,value)
}

变量赋值

v1 := map[string]string("n1":"123","n2":"222")
v2 := v1

fmt.Println(v1)//{"n1":"123","n2":"222"}
fmt.Println(v2)//{"n1":"123","n2":"222"}

注意事项:在slice中扩容会导致指向的地址不同,但是在map中扩容后依然会指向同一地址

底层原理

map由hmap和bmap两个结构体构成

1.hmap中包含map的键值对个数count,哈希因子hash0,用于对key生成hash值,创建bmap的数B,B决定创建桶的个数,是2的B次方

2.将键值对放入bmap,一个bmap中可以 放8个键值对,bmap一般叫做桶,bmap中包含tophash(hash值的高8位),key,value,overflow(指针指向溢出桶)

初始化

//初始化一个可容纳10个元素的map
info := make(map[string]string,10)

第一步:创建一个hmap的结构体对象

第二步:生成一个哈希因子hash0并赋值到hmap中

第三步:根据hint=10,并根据算法规则来创建B,当前B应该为1,创建的桶是2的一次方就是2个桶

hint     B
0-8      0     
9-13     1  
14-26    2
...

第四步:当B少于4时,桶的个数是2的B次方

当B大于等于4时,根据B创建桶的个数规则为2的B次方+2的B减4次方(标准桶加溢出桶)

注释:每个bmap中可以存放8个键值对,当不够存储时需要使用溢出桶,并将当前bmap中的overflow字段指向溢出桶的位置

写入数据

info["n1"] = "111"

在map中写入数据的流程

  • 第一步:结合hmap中的哈希因子和键n1生成哈希值
  • 第二步:获取哈希值的后B位(B为1就取后一位,B为0时就只有一个桶,不需要考虑放入哪个桶),并根据B的值来决定键值对放到哪个桶中
假设B为1,将桶掩码(B的二进制)和哈希值进行&运算,得到的值决定放入哪个桶
哈希值0101010...100100
桶掩码0000000...000001
结果00000000...000 = 0
  • 第三步:确定桶后在桶中写入数据
获取哈希值的高8位tophash,key,value,指向溢出桶的指针overflow

读取数据

value := info[“n1]
  • 第一步:结合哈希因子和键生成hash值
  • 第二步:获取哈希值的后B位,并根据后B位的值来决定放在哪个桶里
  • 第三步:确定桶之后,在根据key的哈希值计算出桶的tophash(高8位),根据tophash和key取桶中查找数据,查找不到会去溢出桶中查找,均未查找到则表示key不存在

扩容

触发扩容的条件:

  • map中数据总个数/桶的个数 > 6.5 ,引发翻倍扩容

  • 使用了太多的溢出桶时,也会引发扩容(溢出桶过多会导致map处理过慢),溢出桶过多会引发等量扩容,创建跟溢出桶同样数量的标准桶

    当B <= 15时,已使用的溢出桶个数 >= 2的B次方时,引发等量扩容

    当B > 15时,已使用的溢出桶个数>= 2的15次方,引发等量扩容

迁移

标签:key,map,hash,string,golang,了解,哈希,data
From: https://www.cnblogs.com/zhuzhangy/p/16754563.html

相关文章

  • 源码角度了解Skywalking之建立连接与服务注册
    源码角度了解Skywalking之建立连接与服务注册这篇文章主要讲一下Agent与OAP建立连接并进行服务注册。从SkyWalking的启动流程SkyWalkingAgent的premain()中我们了解到调用......
  • 源码角度了解Skywalking之Trace信息的生成
    源码角度了解Skywalking之Trace信息的生成TraceId是分布式链路的一个信息,可以通过它定位一条链路TraceId的生成Skwalking的TraceId的生成是通过GlobalIdGenerator的gener......
  • golang channel底层结构和实现
    一、介绍Golang设计模式:不要通过共享内存来通信,而要通过通信实现内存共享channel是基于通信顺序模型(communicationsequentialprocesses,CSP)的并发模式,可以让一......
  • golang GC原理
    一、堆栈栈(heap):由操作系统自动分配释放。一般函数内部执行中声明的变量,函数返回时直接释放,不会引起垃圾回收,对性能无影响堆(stack):一般由程序员分配释放,若程序......
  • 一文带你了解DAS、SAN和NAS三种存储方式
    DAS全称为直接附加存储(DirectAttachedStorage,DAS),是一种直接附加存储,将存储设备通过SCSI接口或光纤通道直接连接到一台计算机上,代表为磁盘阵列柜RAID。磁盘阵列柜是由多......
  • 初学者了解的Java!
    简单看JavaJava的诞生和发展Java是由SunMicrosystems公司于1995年5月推出的Java面向对象程序设计语言和Java平台的总称。由JamesGosling和同事们共同研发......
  • 了解延迟段创建
    当您在本地管理的表空间中创建堆组织表时,数据库会延迟表段的创建,直到插入第一行。此外,对于表的任何LOB列、作为表创建的一部分隐式创建的任何索引以及随后在表上显式创......
  • springboot项目 报错No mapping for GET /css/bootstrap.css,前端无法展示样式
    说来也奇怪,前几天刚写完的项目写的好好的现在打开他就加载不了前端的静态资源了报错NomappingforGET/css/bootstrap.css解决方法:新建一个配置类,将静态资源的路径......
  • 25个构建Web项目的HTML建议,你需要了解一下!
    html超文本标记语言是一种用于创建网页的标准标记语言。html是一种基础技术,常与css、JavaScript一起被众多网站用于设计网页、网页应用程序以及移动应用程序的用户界面。HT......
  • 15分钟了解sql注入(一) union注入
    ......