哈希表是计算机科学中最重要的数据结构之一。许多哈希表的实现有着千差万别的特性,但是总体上他们都提供了快速查询,添加和删除功能。go语言提供了内置数据类型map。

映射是一种内置的数据结构,用来保存键值对的无序集合。

map的声明格式如下:

1、map[KeyType] ValueType

KeyType类型必须是可以比较的,而ValueType可以是任意类型,甚至是另一个map

2、以下这个m是一个键值为string,值为int的哈希表:var m map[string]int

3、哈希表类型是引用类型,像指针或者切片m指向的值是nil;它没有指向一个初始化了的哈希表。一个nil哈希表在读的时候,像一个空的哈希表,但是尝试向m中写数据会引发一个运行时panic,所以别那样做。 使用内置函数make初始化一个哈希表

m = make(map[string]int)//make函数申请并初始化了一个哈希表的数据结构并且返回一个指向这个初始化好了的哈希表

映射的创建:

1、make(map[KeyType]ValueType,initialCapacity)

2、make(map[KeyType]ValueType)

3、map[KeyType]ValueType{}

4、map[KeyType]ValueType{key1:value1,key2:value2.....,keyN:valueN}

egg:

packagemain

import"fmt"

funcmain(){

map1:=make(map[string]string,5)

map2:=make(map[string]string)

map3:=map[string]string{}

map4:=map[string]string{"a":"1","b":"2","c":"3"}

fmt.Println(map1,map2,map3,map4)

}

映射的填充和遍历

packagemain

import"fmt"

funcmain(){

map1:=make(map[string]string)

map1["a"]="1"

map1["b"]="2"

map1["c"]="3"

fmt.Println(map1)

forkey,value:=rangemap1{

fmt.Printf("%s--->%s\n",key,value)

}

}

##map是对key-value的遍历,直接操作value是值得拷贝,只有对key的操作才是修改value

packagemainimport"fmt"funcmain(){sm:=make([]map[int]string,5)for_,value:=rangesm{value=make(map[int]string,1)value[1]="OK"fmt.Println(value)}fmt.Println(sm)}C:/Users/cherry/go/src/test/test.exe[C:/Users/cherry/go/src/test]map[1:OK]map[1:OK]map[1:OK]map[1:OK]map[1:OK][map[]map[]map[]map[]map[]]值得拷贝操作####packagemain

import"fmt"

funcmain(){

sm:=make([]map[int]string,5)

fori:=rangesm{

sm[i]=make(map[int]string,1)

sm[i][1]="OK"

fmt.Println(sm[i])

}

fmt.Println(sm)

}

映射的查找、修改和删除

packagemain

import"fmt"

funcmain(){

map1:=map[string]string{"a":"1","b":"2","c":"3"}

val,exist:=map1["a"]//

val2,exist2:=map1["d"]

fmt.Printf("%v,%v\n",exist,val)

fmt.Printf("%v,%v\n",exist2,val2)

map1["a"]="9"//修改

fmt.Printf("%v\n",map1)

delete(map1,"b")\\删除

fmt.Printf("%v\n",map1)

}

map指定key取对应的value时,可以指定返回两个值,第一个是对应的value,第二个是一个bool,表示是否有值。如上,"a"肯定有值,"b"肯定没值,修改映射和添加映射的操作没什么区别,若指定的键不存在则创建,否则,修改之


MAP并发:


哈希表在有并发的场景并不安全:同时读写一个哈希表的后果是不确定的。如果你需要使用goroutines同时对一个哈希表做读写,对哈希表的访问需要通过某种同步机制做协调。一个常用的方法是是使用sync.RWMutex。

这个语句生命了一个counter变量,这是一个包含了一个map和sync.RWMutex的匿名结构体


##当map多层嵌套的时候,需要对它进行初始化操作,如:egg:

packagemain

import"fmt"

funcmain(){

varmmap[int]map[int]string

m=make(map[int]map[int]string)//这里其实只对外层的map做了初始化操作

a,ok:=m[2][1]

fmt.Println(a,ok)

if!ok{

m[2]=make(map[int]string)

}

m[2][1]="Good1"

a,ok=m[2][1]

fmt.Println(a,ok)

}