map介绍
-
map
是key-value
数据结构,又称为字段或者关联数组。类似其它编程语言的集合。
基本语法
- var map的变量名
map
(关键字)[keyType]
valueType
1、key
可以是什么类型
golang
中的map
可以是多种类型,比如bool,数字,string,指针,channel(管道)
,还可以是只包含前面几个类型的 接口,结构体,数组,
通常是int
,string
-
slice map function
不可做为key
的数据类型。
2、valueType
可以是什么类型
valueType
的类型和key
基本一样,通常为:数字(整数,浮点数),string,map,struct
map的声明
var a map[string]string
var a map[string]int
var a map[int]string
//a 的key是string类型,value是map类型。
var a map[string]map[string]string
声明
是不会分配内存,初始化要用make
,分配内存后才能赋值和使用
。
var a map[string]string
//使用map前,需要先make,make的作用就是分配内存空间。
a = make(map[string]string, 10) //10代表10对k-v的空间
//key不可以重复,key相同的话,后面的覆盖前面
a["no1"] = "宋江"
a["no2"] = "吴用"
a["no1"] = "武松"
a["no3"] = "林冲"
//map中是无序的k-v
fmt.Println(a)
- 以上代码的说明
1、map在使用前一定要make。
2、map的key是不能重复的。相同的话,后面覆盖前面。
3、map的value可以相同。
4、map的key-value是无序的。
map的使用方式
1、方式1:先声明,再make,再赋值
//第一种方式: 先声明再 make
var a map[string]string
//使用map前,需要先make,make的作用就是分配内存空间。
a = make(map[string]string, 10) //10代表10对k-v的空间
//key不可以重复,key相同的话,后面的覆盖前面
a["no1"] = "宋江"
a["no2"] = "吴用"
a["no1"] = "武松"
a["no3"] = "林冲"
//map中是无序的k-v
fmt.Println(a)
2、方式2:声明的时候直接 make
//第二种方式 声明的时候 make 用到类型推导
cities := make(map[string]string)
cities["no1"] = "北京"
cities["no2"] = "天津"
cities["no3"] = "上海"
fmt.Println(cities)
3、方式3:声明的时候直接赋值
//第三种方式 声明,直接赋值 用到类型推导
heroes := map[string]string{
"hero1": "宋江",
"hero2": "林冲",
"hero3": "武松",
}
heroes["hero4"] = "卢俊义"
fmt.Println(heroes)
案例:
我们要存放三个学生的信息,每个学生有
name
和sexs
的信息
思咱:map [string]map[string]string
(一对多)
studentMap := make(map[string]map[string]string)
//value 类型是map,所以还要 make
studentMap["stu01"] = make(map[string]string, 3)
studentMap["stu01"]["name"] = "tom"
studentMap["stu01"]["sex"] = "男"
studentMap["stu01"]["add"] = "北京长安街"
studentMap["stu02"] = make(map[string]string, 3)
studentMap["stu02"]["name"] = "mary"
studentMap["stu02"]["sex"] = "女"
studentMap["stu02"]["add"] = "上海陆家嘴"
fmt.Println(studentMap)
fmt.Println(studentMap["stu02"])
fmt.Println(studentMap["stu02"]["add"])
map的增删改查操作
1、map
的增加和更新:
map["key"] = value
key
不存在就是增加,存在就是更新
2、 map
的删除
delete(map名称,"key"),delete
是一个内置函数,如果key
存在,就删除该key-value
,如果key
不存在,不操作,但是也不会报错。
cities := make(map[string]string)
cities["no1"] = "北京"
cities["no2"] = "天津"
cities["no3"] = "上海"
cities["no4"] = "广州"
fmt.Println(cities)
//删除操作
delete(cities, "no1")
fmt.Println(cities)
map
删除说明:
1、如果我们要删除map
的所有key
,只能遍历key
,逐个删除。
2、或者map = amke(...)
,make
一个新的,让原来的变为垃圾,被gc
回收
//如果希望一次性删除所有的key
//1、遍历所有的key,逐个删除
//2、make一个空间
cities = make(map[string]string)
fmt.Println(cities)
3、map查找
//map查找
val, ok := cities["no2"]
if ok {
fmt.Printf("找到 no2 key,值为%v\n", val)
} else {
fmt.Println("没有找到 no2 key")
}
查找到 ok 返回true,查不到 ok返回false
map的遍历
-
map
的遍历使用for-range
的结构遍历 - 案例:
cities := make(map[string]string)
cities["no1"] = "北京"
cities["no2"] = "天津"
cities["no3"] = "上海"
cities["no4"] = "广州"
for k, v := range cities {
fmt.Printf("k=%v,v=%v\n", k, v)
}
fmt.Println()
studentMap := make(map[string]map[string]string)
//value 类型是map,所以还要 make
studentMap["stu01"] = make(map[string]string, 3)
studentMap["stu01"]["name"] = "tom"
studentMap["stu01"]["sex"] = "男"
studentMap["stu01"]["add"] = "北京长安街"
studentMap["stu02"] = make(map[string]string, 3)
studentMap["stu02"]["name"] = "mary"
studentMap["stu02"]["sex"] = "女"
studentMap["stu02"]["add"] = "上海陆家嘴"
for k1, v1 := range studentMap {
fmt.Println("k1=", k1)
for k2, v2 := range v1 {
fmt.Printf("\t k2=%v,v2=%v\n", k2, v2)
}
fmt.Println()
}
map长度 用 len内置函数来求
fmt.Println(len(map的名称))
map切片 (很重要)
切片的数据类型如果是
map
,则我们称为map切片
,这样使用则map个数就可以动态变化
了。案例:
使用map来记录一个
monster
的age和name,一个monster对应一个map,并且monster
的个数可以动态增加。
var monster []map[string]string
//切片本身也要make
monster = make([]map[string]string, 2) //准备放2个妖怪
//增加第一个妖怪
if monster[0] == nil {
monster[0] = make(map[string]string, 2)
monster[0]["name"] = "牛魔王"
monster[0]["age"] = "500"
}
if monster[1] == nil {
monster[1] = make(map[string]string, 2)
monster[1]["name"] = "白骨精"
monster[1]["age"] = "400"
}
//动态增加map切片用 append函数
//1、先定义一个monster信息
newMonster := map[string]string{
"name": "新的妖怪",
"age": "690",
}
monster = append(monster, newMonster)
fmt.Println(monster)
map的排序
1、golang没有专门方法给map的key进行排序
2、golang中的map默认是无序的,每次输出的结果都不一样
3、golang中的map的排序,是先将key进行排序,然后跟据key值遍历输出即可。
package main
import (
"fmt"
"sort"
)
func main() {
//map排序
map1 := make(map[int]int, 10)
map1[10] = 100
map1[1] = 13
map1[4] = 56
map1[8] = 90
fmt.Println(map1)
//1、先将map的key放到一个切片中
//2、对切片进行排序
//3、遍历切片,然后按照key输出map的值
var keys []int
for k, _ := range map1 {
keys = append(keys, k)
}
//排序
sort.Ints(keys)
fmt.Println(keys)
//遍历keys,通过key取出map
for _, k := range keys {
fmt.Printf("map1[%v]=%v\n", k, map1[k])
}
}
map使用细节
1、map
是引用类型,遵守引用类型传递机制,在一个函数中接收map
,修改后,会直接修改原来的map
func modify(map1 map[int]int) {
map1[10] = 100
}
func main() {
map1 := make(map[int]int)
map1[1] = 90
map1[2] = 88
map1[10] = 1
map1[20] = 111
fmt.Println(map1)
modify(map1)
fmt.Println(map1)
}
2、map
的容量超出指定的容量,会动态扩容,不会发生panic
3、map
的value
也经常使用struct 类型
,更适合管理复杂的数据(比前面value
是一个map
更好)
package main
import (
"fmt"
_ "sort"
)
//定义结构体
type Stu struct {
Name string
Age int
Add string
}
func main() {
//map的value 也经常为struct 类型
//更适合管理复杂的数据(比前面value是一个map更好)
//比如value为student结构体
//1、map的key为学生的学号。是唯一的
//2、map的value为结构体,包含学生的名字,年龄,地址
students := make(map[string]Stu, 10)
//创建两个学生
stu1 := Stu{"tom", 18, "广州市天河区"}
stu2 := Stu{"mary", 28, "惠州市惠城区"}
students["no1"] = stu1
students["no2"] = stu2
fmt.Println(students)
//遍历各个学生的信息
for k, v := range students {
//v现在是一个结构体
fmt.Printf("学生的编号是:%v\n", k)
fmt.Printf("学生的名字是:%v\n", v.Name)
fmt.Printf("学生的年龄是:%v\n", v.Age)
fmt.Printf("学生的地址是:%v\n", v.Add)
fmt.Println()
}
}
package main
import (
"fmt"
_ "sort"
)
//定义结构体
func modifyUser(users map[string]map[string]string, name string) {
val, ok := users[name]
if ok {
fmt.Println("找到了。。。=", val)
//找到了把map里面的pwd,修改
users[name]["pwd"] = "888888"
} else {
fmt.Println("没找到????")
users[name] = make(map[string]string, 2)
users[name]["nickname"] = "newU"
users[name]["pwd"] = "888888"
}
}
func main() {
users := make(map[string]map[string]string)
//make value
users["song"] = make(map[string]string, 2)
users["song"]["nickname"] = "steven"
users["song"]["pwd"] = "12345678"
users["boby"] = make(map[string]string, 2)
users["boby"]["nickname"] = "bily"
users["boby"]["pwd"] = "09090909"
fmt.Println(users)
modifyUser(users, "sss")
fmt.Println(users)
}