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
	})
}
相关推荐
不穿格子的程序员17 小时前
从零开始写算法——普通数组篇:缺失的第一个正数
算法·leetcode·哈希算法
Nebula_g17 小时前
线程进阶: 无人机自动防空平台开发教程(更新)
java·开发语言·数据结构·学习·算法·无人机
独自破碎E17 小时前
大整数哈希
算法·哈希算法
xuxie9918 小时前
day 23 树
数据结构
EnglishJun19 小时前
数据结构的学习(四)---栈和队列
数据结构·学习
数智工坊20 小时前
【数据结构-特殊矩阵】3.5 特殊矩阵-压缩存储
数据结构·线性代数·矩阵
芝士爱知识a20 小时前
AlphaGBM 深度解析:下一代基于 AI 与蒙特卡洛的智能期权分析平台
数据结构·人工智能·python·股票·alphagbm·ai 驱动的智能期权分析·期权
兩尛20 小时前
160. 相交链表/c++
数据结构·链表
历程里程碑20 小时前
普通数组----最大子数组和
大数据·算法·elasticsearch·搜索引擎·排序算法·哈希算法·散列表
2302_8138062220 小时前
【嵌入式修炼:数据结构篇】——单向链表的排序
数据结构·链表·排序算法