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
	})
}
相关推荐
qq_4523962322 分钟前
第五篇:《接口与错误处理:Go 的哲学》
开发语言·后端·golang
yuannl102 小时前
图的深度优先遍历DFS
数据结构
布朗克1682 小时前
Go 入门到精通-29-测试与基准
开发语言·后端·golang·测试与基准
青山木5 小时前
Hot 100 --- 岛屿数量
java·数据结构·算法·leetcode·深度优先·广度优先
不会就选b5 小时前
算法日常・每日刷题--<归并排序>1
数据结构·算法
危桥带雨6 小时前
排序算法(快排、归并、计数、基数排序)
数据结构·算法·排序算法
zephyr056 小时前
数据结构-并查集
数据结构
稚南城才子,乌衣巷风流7 小时前
动态树(Dynamic Tree)数据结构详解
数据结构·算法
zander2587 小时前
114. 二叉树展开为链表
数据结构·链表·深度优先
止语Lab8 小时前
从 PHP 到 Go:真正迁移的是复杂度的归属
android·golang·php