map

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

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • GO 中map的底层是如何实现的 首先Go 语言采用的是哈希查找表,并且使用链表解决哈希冲突。 GO的内存模型 先...
    GGBond_8488阅读 2,019评论 2 4
  • 什么是Map 维基百科的定义 In computer science, an associative array,...
    爱情小傻蛋阅读 1,672评论 1 2
  • 本文目录如下,阅读本文后,将一网打尽下面Golang Map相关面试题 面试题 map的底层实现原理 为什么遍历m...
    Go程序员阅读 1,166评论 0 3
  • 映射 map 什么是 map map 是由一组键值对组成的抽象数据结构,并且键只会出现一次。 map 通常是用哈希...
    朱建涛阅读 870评论 0 2
  • 映射是一种数据结构,用于存储一系列无序的键值对。 映射是一个集合,可以使用类似处理数组和切片的方式迭代,但映射是无...
    王侦阅读 149评论 0 0