Map 官方介绍
One of the most useful data structures in computer science is the hash table. Many hash table implementations exist with varying properties, but in general they offer fast lookups, adds, and deletes. Go provides a built-in map type that implements a hash table.
哈希表是计算机中最有用的数据结构之一。提供快速查找、添加和删除。 Go 提供了一个实现哈希表的内置Map类型。
Hash冲突
那对于Hash的一个最重要的问题,就是hash冲突。下面我们看一下常用的解决方案。
开放寻址法
开放寻址法想象成一个停车问题。若当前车位已经有车,则继续往前开,直到找到一个空停车位。
上图,每个方格子,就是一个车位,当一辆车来的时候,会依次查询是否有空位,如果没有,则继续向后面找,如果发现空位置,就会停到空位置中。
下面看一下,我们的代码是如何实现的?
- m[“面向加薪学习”]=“从0到Go语言微服务架构师-训练营”
- 要对键-“面向加薪学习”,进行hash
- 拿到全体格子的总数,然后取模
- 如果取模发现是位子1,但是发现1已经被别人占了,那么就向后走,直到有空位,再把自己放进去。
看了上面的步骤是不是和停车,是一个道理?
那我们再看,如果想读取数据的时候:
- 同样对J键进行hash
- 拿到全体格子的总数,然后取模
- 找到位置是1,但是发现key不一样,它可能在后面,就一直向后查找。
拉链法
- m[“面向加薪学习”]=“从0到Go语言微服务架构师-训练营”
- 要对键-“面向加薪学习”,进行hash
- 找到对应到槽位,每个槽位并不存储具体数据,只是一个指针,它指向下面的链表
- 当新增数据的时候,会把数据添加到链表头部(上图中黄色小球为例)
Go语言的Map
runtime/map.go,看到hmap这个结构体,它就go语言的map
type hmap struct {
count int
flags uint8
B uint8
noverflow uint16
hash0 uint32
buckets unsafe.Pointer
oldbuckets unsafe.Pointer
nevacuate uintptr
extra *mapextra
}
- count 键值对的数量
- B 是以2为底,桶个数的对数
- hash0 hash的种子