map

作者: 我帅的不忍直视 | 来源:发表于2023-11-23 19:13 被阅读0次

map本质上是一个桶数组,一个桶最多存储 8 个键值对,一个健通过哈希函数,可以固定的映射到一个桶中,然后在桶内通过遍历 8 个健的 方式来寻找正确的键值对位置。如果 有 多于 8 个元素映射到一个桶,则需要分配一个溢出桶来存储,每个桶都保留一个指针,用来指向溢出桶(开放地址寻址法)。

计算哈希值,需要两个输入,一个是哈希函数,一个是哈希种子。

在golang中,哈希函数是固定的,string类型的key,对应哈希函数是hashstr。

哈希种子 hash0 在创建时生成,在整个map存活区间,一般不会变。

但是有个特例,当 删除map 的key,且删除到key 的数量为0 时,会重新生成要给 hash0.

正常桶的个数 = 2的B次方。

扩容

hash map 有个负载因子的概念: 负载因子 = count(元素个数) / 2^B(桶的个数)

情况1: 当负载因子 > 6.5 的 时候,就进行翻倍扩容

扩容规则

map扩容时使用渐进式扩容

由于 map 扩容需要将原有的 key/value 重新搬迁到新的内存地址,如果map存储了数以亿计的key-value,一次性搬迁将会造成比较大的延时,因此 Go map 的扩容采取了一种称为**“渐进式”的方式,原有的 key 并不会一次性搬迁完毕,每次最多只会搬迁 2 个 bucket。只有在插入或修改、删除 key 的时候,都会尝试进行搬迁 buckets 的工作**。先检查 oldbuckets 是否搬迁完毕,具体来说就是检查 oldbuckets 是否为 nil。

var map 变量名 map[keytype]valuetype

key 可以是什么类型 :golang 中的 map,的 key 可以是很多种类型,比如 bool, 数字,string, 指针, channel , 还可以是只 包含前面几个类型的 接口, 结构体, 数组

通常 key 为 int 、string     注意: slice, map 还有 function 不可以,因为这几个没法用 == 来判断,不是可比较类型 

valuetype 可以是什么类型: valuetype 的类型和 key 基本一样,这里我就不再赘述了 通常为: 数字(整数,浮点数),string,map,struct

相关文章

网友评论

      本文标题:map

      本文链接:https://www.haomeiwen.com/subject/yydgwdtx.html