map的数据结构,扩容机制,key是无序的原因

map就相当于是一个超级查询表,给它一个Key,它可以给你返回对应的value。例如

Go 复制代码
m := map[string]int{
    "apple":  3,
    "banana": 5,
}
fmt.Println(m["apple"]) // 3

以上例子,Apple就是Key,3就是代表的value。

原理分析:

(1)哈希表:Go中的map实现基于哈希表。哈希表是一种数据结构,通过哈希函数将键映射到存储桶(bucket)中,哈希表的主要优点是可以在平均时间复杂度为 O(1) 的时间内实现快速的查找、插入和删除操作。

(2)哈希函数:哈希函数将键映射为唯一的哈希值。在Go中,哈希函数会将键的二进制表示转换成一个固定长度的哈希值。这个哈希值会被映射到哈希表中的一个桶中。

(3)桶(bucket):哈希表由多个桶组成,每个桶存储具有相同哈希值的键值对。当发生哈希冲突时,即多个键映射到同一个桶中,通常使用链表或者其他数据结构来存储这些键值对,以实现冲突的解决。

(4)动态扩容:为了避免哈希表中桶的过度填充,Go 中的map实现会在适当的时候自动进行动态扩容。当map中的键值对数量达到一定阈值时,Go 会创建一个新的更大的哈希表,并重新哈希所有的键值对到新的桶中。

(5)哈希冲突处理:哈希冲突是指不同的键映射到相同的哈希值的情况。在哈希表中,通常使用链表或其他方式来解决哈希冲突。当插入新的键值对时,如果发生了哈希冲突,新的键值对会被添加到对应桶的链表中。

Go 复制代码
package main

import (
	"fmt"
	"sync"
)

func main() {
	// 创建一个线程安全的 map
	var myMap sync.Map

	// 使用 Store 方法向 map 中存储键值对
	myMap.Store("apple", 10)
	myMap.Store("banana", 20)
	myMap.Store("orange", 30)

	// 使用 Load 方法从 map 中加载值
	value, exists := myMap.Load("banana")
	if exists {
		fmt.Println("Value of banana:", value)
	}

	// 使用 Delete 方法从 map 中删除键值对
	myMap.Delete("banana")

	// 使用 Range 方法遍历 map 中的所有键值对
	myMap.Range(func(key, value interface{}) bool {
		fmt.Println("Key:", key, "Value:", value)
		return true
	})
}
相关推荐
YSL0701248 分钟前
一文通关-----排序
数据结构·算法
利威尔xu10 小时前
Go IM 源码实战(14):本地缓存快 3000 倍,失效却难 10 倍
后端·缓存·微服务·面试·golang
利威尔xu11 小时前
Go IM 源码实战(13):30 个会话只有 2 个红点,未读数错在三条路径
redis·后端·微服务·面试·golang
FungLeo12 小时前
成为全栈·Go 后端篇·从 Node SQLite 到 PostgreSQL:把迁移做成独立交付物
postgresql·golang·sqlite·go·数据库迁移·成为全栈
夜不会漫长13 小时前
C++:红黑树
数据结构·算法
冻柠檬飞冰走茶16 小时前
PTA刷题集之Airline Routes(C语言实现)
c语言·开发语言·数据结构·算法
736c16 小时前
固件开发岗算法
数据结构·算法
冻柠檬飞冰走茶16 小时前
PTA刷题集之Battle Over Cities - Hard Version(C语言实现)
c语言·开发语言·数据结构·算法
皓月盈江17 小时前
GO使用Gin框架实现模板定义、解析与渲染
linux·golang·go·gin·定义模板·解析模板·渲染模板