1.注意事项
在使用map这一数据结构时,一定要初始化。未初始化的map变量默认为nil,此时添加元素会触发panic
2.增、删、改、查四种基本操作
2.1 增
一定要注意在添加元素时,若键已经存在,此时程序不会报错,新值会覆盖旧值。因此在添加元素时要判断键是否存在
func Map(){
var mymap map
mymap = (make[string]int,10)
_,ok=mymap["apple"]//查找apple键是否存在
if !ok{
mymap["apple"]=10//如果不存在则添加键为apple,值为10
}
}
2.2 删
删除使用内置函数delete,它没有返回值因此不需要考虑是否会报错
func Map(){
var mymap map
mymap = (make[string]int,10)
/*
增
*/
_,ok=mymap["apple"]//查找apple键是否存在
if !ok{
mymap["apple"]=10//如果不存在则添加键为apple,值为10
}
/*
删
*/
delete(mymap,"apple")//删除apple键及值
delete(mymap,"tom")//仍然不会报错会继续向下运行
}
2.3 改
通过键直接修改对应的值,若键不存在那么则变成 ‘增’ 操作
func Map(){
var mymap map
mymap = (make[string]int,10)
/*
增
*/
_,ok=mymap["apple"]//查找apple键是否存在
if !ok{
mymap["apple"]=10//如果不存在则添加键为apple,值为10
}
/*
删
*/
delete(mymap,"apple")//删除apple键及值
delete(mymap,"tom")//仍然不会报错会继续向下运行
/*
改
*/
mymap["apple"]=5//修改键为apple的值为5
mymap["tom"]=2//由于“tom”键不存在,因此修改操作变成增加操作
}
2.4 查
可以给两个变量赋值,第一个为值,第二个是bool类型变量用于反应键是否存在。若不存在值为对应变量的零值。
func Map(){
var mymap map
mymap = (make[string]int,10)//初始化map,并使其初始容量为10
/*
增
*/
_,ok=mymap["apple"]//查找apple键是否存在
if !ok{
mymap["apple"]=10//如果不存在则添加键为apple,值为10
}
/*
删
*/
delete(mymap,"apple")//删除apple键及值
delete(mymap,"tom")//仍然不会报错会继续向下运行
/*
改
*/
mymap["apple"]=5//修改键为apple的值为5
mymap["tom"]=2//由于“tom”键不存在,因此修改操作变成增加操作
/*
查
*/
v,ok=mymap["apple"]//存在,ok为true,此时v=5
v,ok=mymap["jack"]//不存在,ok为false,此时v=0
}
3.实现原理
Go语言的map使用Hash表作为底层实现
3.1 Hash是什么
Hash又称为"散列",是一种与排序相反的操作。通过计算哈希值,打破元素之间原有的关系,使集合中的元素按照散列函数的分类进行排列。
3.2 为什么要有Hash
在使用数组链表存储元素时,存储元素一旦过多,在查找某个元素是否存在过程中,数组和链表需要一个一个循环比较,时间复杂度会大幅增加。而通过哈希计算,则大大减少了比较次数。即哈希表实现了数据的快速查找。
3.3 哈希冲突
冲突的定义及解决冲突
哈希冲突是指不同的值通过哈希计算被分到相同的bucket
例:
解决哈希冲突的方法:Golang的map采用链地址来解决这个问题,即在同一个位置存储一个键值对链表。当发生冲突时,新的键值对会被添加到这个链表的末尾。
产生冲突往往跟关键字的比较次数密切相关,产生的冲突少查找的效率就高。
与冲突相关的因素
1.哈希函数是否均匀
2.处理冲突的方法
3.哈希表的加载因子