map是key-value结构的数据类型,类似于其他语言中的hash table,dict等
key必须是可hash的值,是一个确定的值(key的值不能设置了之后又发生了改变)
map存储的时候 hash(key) --> 固定的值 --> 把value放到对应的位置保存
map[key] : hash(key) --> 得到值 --> 取对应的value
GO语言中map
的定义语法如下:
map[KeyType]ValueType
其中,
map类型的变量默认初始值为nil,需要使用make()函数初始化分配内存。语法为:
make(map[KeyType]ValueType,[cap])
其中cap表示map的容量,该参数虽然不是必须的,但是我们应该在初始化map的时候为其指定一个合适的容量。
map初始化的方法有字面量初始化,make()函数初始化。
字面量初始化:
//字面量初始化
func f18() {
var m map[string]int
fmt.Println(m == nil) // true。map未初始化,值为nil
m1 := map[string]string{
"username": "王磊",
"password": "1234", //花括号换行此处必须加逗号
}
fmt.Printf("%#v\n", m1) //
}
//运行结果:
true
map[string]string{"password":"1234", "username":"王磊"}
make()函数初始化:
//make函数初始化
func f19() {
m2 := make(map[string]int) //只要初始化就可以赋值
fmt.Println(m2 == nil) //false,因为map已经初始化
m2["wanglei"] = 120 //设置值
fmt.Println(m2)
weight := m2["wanglei"] //取值
fmt.Println(weight)
}
//运行结果:
false
map[wanglei:120]
120
GO语言中有个判断map中键是否存在的特殊写法,格式如下:
value,ok := map[key]
举个例子:
//判断key是否存在
func f20() {
m3 := make(map[string]int)
m3["wanglei"] = 120
m3["jack"] = 200
// v,ok取值;OK是一个变量名,只不过大家约定俗成在这里用ok
// OK=true表示map有这个key,ok=false表示map没这个key
//如果没这个key,v等于对应类型的零值
v, ok := m3["wanglei"]
fmt.Println(v, ok) // 120 true
v1, ok := m3["name"]
fmt.Println(v1, ok) //0 false
_, ok = m3["mike"]
fmt.Println(ok) //false
}
//运行结果:
120 true
0 false
false
// map的遍历(map是无序的)
func f21() {
m4 := map[string]int{
"wanglei": 120,
"小和尚": 200,
"shahe": 234,
}
//遍历键和值
for k, v := range m4 {
fmt.Println(k, v)
}
//只遍历键
for k1 := range m4 {
fmt.Println(k1)
}
//只遍历值
for _, v1 := range m4 {
fmt.Println(v1)
}
}
//运行结果:
wanglei 120
小和尚 200
shahe 234
wanglei
小和尚
shahe
120
200
234
使用delete()内建函数从map中删除一组键值对,delete()函数的格式如下:
delte(map,key)
其中,
// 从map中删除键值对
func f22() {
m5 := make(map[string]int)
m5["猪八戒"] = 200
m5["孙悟空"] = 100
m5["唐僧"] = 150
delete(m5, "猪八戒")
for k, v := range m5 {
fmt.Printf("键为:%v 值为:%v\n", k, v)
}
}
//运行结果:
键为:孙悟空 值为:100
键为:唐僧 值为:150
//元素为map类型的切片
func f23() {
mapSlice := make([]map[string]string, 3) //定义了一个元素为map类型的,len=cap=3的切片
fmt.Println(mapSlice)
for index, value := range mapSlice {
fmt.Printf("index:%d value:%v\n", index, value) // 得到的value都为map[]
}
fmt.Println("----------------after init----------------")
//对切片的元素进行初始化
mapSlice[0] = make(map[string]string)
mapSlice[0]["name"] = "小王子"
mapSlice[0]["password"] = "123456"
mapSlice[0]["address"] = "沙河"
fmt.Println(mapSlice)
for index, value := range mapSlice {
fmt.Printf("index:%d value:%v\n", index, value)
}
//继续可以按照对mapSlice[1],mapSlice[2]的元素初始化...
}
//运行结果:
[map[] map[] map[]]
index:0 value:map[]
index:1 value:map[]
index:2 value:map[]
----------------after init----------------
[map[address:沙河 name:小王子 password:123456] map[] map[]]
index:0 value:map[address:沙河 name:小王子 password:123456]
index:1 value:map[]
index:2 value:map[]
//值为切片类型的map
func f24() {
sliceMap := make(map[string][]string)
fmt.Println(sliceMap)
fmt.Println("-----------------after int-----------------")
key := "中国"
value, ok := sliceMap[key]
if !ok {
value = make([]string, 0, 2)
}
value = append(value, "北京", "上海")
sliceMap[key] = value //map赋值
fmt.Println(sliceMap)
}
//运行结果:
map[]
-----------------after int-----------------
map[中国:[北京 上海]]
1、写一个程序,统计一个字符串中每个单词出现的次数。比如:”how do you do”中how=1 do=2 you=1。
//写一个程序,统计一个字符串中每个单词出现的次数。比如:"how do you do"中how=1 do=2 you=1
func f25() {
/*
1、先把字符串每个单词统计出来
2、统计每个单词的数量
*/
str := "how do you do"
slice := strings.Split(str, " ")
fmt.Println(slice) //[how do you do]
//定义一个map
map1 := make(map[string]int)
for _, value := range slice {
_, ok := map1[value]
if !ok { // 如果key不存在,则给这个key的value赋值1
map1[value] = 1
} else { //如果key存在,则在之前基础上+1
map1[value] += 1
}
}
fmt.Println(map1)
}
//运行结果:
[how do you do]
map[do:2 how:1 you:1]
2、观察下面代码,写出最终打印结果
// 下面代码打印结果
func f26() {
type Map map[string][]int
m := make(Map)
s := []int{1, 2}
s = append(s, 3)
fmt.Printf("%+v\n", s) // [1 2 3]
fmt.Printf("切片s的内存地址是:%p s: %v\n", s, s)
m["q1mi"] = s
fmt.Printf("m的内存地址是:%p m: %v\n", m, m)
s = append(s[:1], s[2:]...)//等价于s[1]=3
fmt.Printf("新切片s的内存地址是:%p s: %v\n", s, s) // 和之前的切片s的内存地址一样,因为底层操作的是同一个数组 [1 3]
fmt.Printf("%+v\n", m["q1mi"]) //map[q1mi:[1 3 3] ?
}
//运行结果
[1 2 3]
切片s的内存地址是:0xc0000b4000 s: [1 2 3]
m的内存地址是:0xc000098180 m: map[q1mi:[1 2 3]]
新切片s的内存地址是:0xc0000b4000 s: [1 3]
[1 3 3]