本章纲要
一、map快速入门
1、map是key-value数据结构,又称为字段或者关联数组。类似其他编程语言的集合,在编程中经常使用
2、基本语法
var map 变量名[keytype]valuetype
3、key的类型
(1)key可以为bool、数字、string、指针、channel
(2)接口、结构体、数组
(3)通常为int 、string
(4)注意:slice、map和function 不可以,因为这几个没有办法用 ==
4、value的类型
(1)和key基本一致
(2)通常为数字、string、map、结构体struct
5、声明
(1)声明是不会分配内存的,初始化需要make,分配内存后才可以赋值和使用
package main
import (
"fmt"
_ "fmt"
)
func main() {
var a map[string]string
a = make(map[string]string,10)
a["名字"]="小明"
a["名字"]="小红"
fmt.Println(a)
}
(2)map的 key 不能重复,如果重重复就会覆盖原来的值
(3)map的 value 可以重复
(4)map的key-value是无序的
二、map的使用
(1)如上,先声明再make
var a map[string]string
a = make(map[string]string,10)
a["名字"]="小明"
a["名字"]="小红"
fmt.Println(a)
(2)声明直接make
var b = make(map[string]string)
fmt.Println(b)
(3)声明直接赋值
var c map[string]string = map[string]string{
"name":"重庆",
}
c["year"]="2018"
fmt.Println(c)
运行结果:
三、map的应用
1、举例
存放学生信息,每个学生(学号)有name和sex,设计一个map
思路:map[string]map[string]string
studentMap :=make(map[string]map[string]string)
studentMap["stu01"] = make(map[string]string,2)
studentMap["stu01"]["name"] = "tom"
studentMap["stu01"]["sex"] = "男"
studentMap["stu02"] = make(map[string]string,2)
studentMap["stu02"]["name"] = "jessy"
studentMap["stu02"]["sex"] = "女"
fmt.Println(studentMap,"\n")
fmt.Println(studentMap["stu02"],"\n")
fmt.Println(studentMap["stu02"]["name"],"\n")
运行结果:
四、map的增删改查
package main
import (
"fmt"
_ "fmt"
)
func main() {
var a map[string]string = make(map[string]string)
//增加
a["no1"] = "a"
a["no2"] = "b"
a["no3"] = "c"
a["no4"] = "d"
fmt.Println(a)
//key不存在 更新(修改)
a["no4"] = "m"
//delete 删除
delete(a,"no1")
fmt.Println(a)
delete(a,"no5") //key不存在时,不进行操作也不报错
fmt.Println(a)
//查询
val, ok :=a["no1"]
if ok{
fmt.Println("no1=",val)
}else {
fmt.Println("没有no1")
}
}
结果:
如果要删除所有key
(1)方法一:
遍历map删除
(2)方法二:
make一个新空间,让原来的成为垃圾,被gc回收
五、map的遍历(for-range)
1、for-range结构遍历
package main
import (
"fmt"
_ "fmt"
)
func main() {
cities :=make(map[string]string)
cities["no1"] = "beijing"
cities["no2"] = "tianjing"
cities["no3"] = "shanghai"
fmt.Println(cities)
for k,v :=range cities{
fmt.Printf("k=%v, v=%v\n",k,v)
}
fmt.Printf("\n")
//较复杂的map遍历
studentMap :=make(map[string]map[string]string)
studentMap["stu01"] = make(map[string]string,2)
studentMap["stu01"]["name"] = "tom"
studentMap["stu01"]["sex"] = "男"
studentMap["stu02"] = make(map[string]string,2)
studentMap["stu02"]["name"] = "jessy"
studentMap["stu02"]["sex"] = "女"
for k1,v1 :=range studentMap{
fmt.Println("k1=",k1)
//k1 stu01,stu02 ..
//v1 map[name][sex]
for k2, v2 :=range v1{
fmt.Printf("\t k2=%v v2=%v\n",k2,v2)
}
fmt.Printf("\n")
}
}
六、map长度 len()
例如:
len(cities)
七、map切片 以及 map增加
1、切片的数据类型如果是map,那么就是map切片,这样就可以使用动态map个数
2、举例:使用一个map来动态记录monster的信息name、age,也就是说每一个monster对应一个map,并且monster的个数可以动态增加——》map切片
package main
import (
"fmt"
_ "fmt"
)
func main() {
var monsters []map[string]string
monsters = make([]map[string]string,2) //切片本身要make
if monsters[0] == nil{
monsters[0] =make(map[string]string,2) //切片对应的数据类型是map也要make
monsters[0]["name"] = "牛魔王"
monsters[0]["age"] = "500"
}
if monsters[1] == nil{
monsters[1] =make(map[string]string,2) //切片对应的数据类型是map也要make
monsters[1]["name"] = "玉兔精"
monsters[1]["age"] = "400"
}
fmt.Print(monsters)
//增加新妖怪,动态增加
newMonster := map[string]string{
"name":"new_monster",
"age":"1000",
}
monsters = append(monsters,newMonster)
fmt.Println(monsters)
}
八、map排序
1、map中是无序的
2、排序思路:
(1)先将map的key放到切片中
(2)对求切片排序
(3)遍历切片,按照key来输出map的值
package main
import (
"fmt"
_ "fmt"
"sort"
)
func main() {
map1 := make(map[int]int)
map1[10] = 100
map1[1] = 13
map1[2] = 15
map1[3] = 8
fmt.Println(map1)
var keys []int
for k,_ :=range map1{
keys=append(keys,k)
}
sort.Ints(keys)
fmt.Println(keys)
//按照k的顺序输出value
for _,k :=range keys{
fmt.Printf("map[%v]=%v ",k,map1[k])
}
用到的排序函数
运行结果:
九、map使用细节
1、map是一个引用类型,在一个函数接受map,修改后,会直接修改原来的map值
2、map的容量扩大后,再想map增加元素,会自动扩容,并不会发生panic,也就是说,map可以动态地增长键值对 (key-value)
3、map的value也经常使用struct类型,更适合管理更复杂的数据,比前面value是一个map更好。比如value为Student结构体
4、综合应用
package main
import (
"fmt"
_ "fmt"
)
func modifyUser(users map[string]map[string]string,name string) {
//判断users里面是否有该用户
if users[name] !=nil{
//有该用户
users[name]["pwd"] = "888888"
}else {
//没有则创建该用户
users[name] = make(map[string]string,2)
users[name]["pwd"] = "888888"
users[name]["nickname"] = "昵称~"+name //示意
}
}
func main() {
users := make(map[string]map[string]string,10)
modifyUser(users,"tom")
modifyUser(users,"marry")
fmt.Println(users)
}
运行结果