go 语言之map
map
map 的声明
map 是key -value 数据结构,又称为字段或者关联数组。类似其他编程语言的集合;在编程中是经常使用到的
基本语法
var map 变量名, map[key type] valuetype
golang 中的map的key 可以是很多种类型,比如bool,数字,string,指针,channel,还可以是包含前面几个类型的接口,结构体,数组通常为int、string
注意 slice ,map 还有function不可以,是因为这几个没法用==来判断
valuetype 可以是什么类型
valuetype 的类型和key 基本一样,通常为数字(整型,浮点数)
声明map
var a map[string]string var b map[string]int var c map[int]string var d map[string]map[string]string
注意声明不会分配内存的,初始化需要make,分配内存后才能赋值使用
初始化
package main
import "fmt"
//"fmt"
func main(){
var a map[string]string//声明
a = make(map[string]string,10)//初始化
a["a1"]= "宋江"
a["a2"]= "吴用"
a["a3"]= "吴用"
a["a1"]= "武松"
a["a4"]= "林冲"//v可以重复;无序的key-v结构go
fmt.Println(a)
}
//执行结果
// PS D:\golang\goproject\src\src01\go_code\src> go run chapter08\deom01\main.go
// map[a1:武松 a2:吴用 a3:吴用 a4:林冲]
1)map 在使用前一定要make
2) map 的key 是不能重复,如果重复key,则覆盖上一个value值
3)map的value 的值是可以重复的
4)map 的key-value 是无序的
make 内置函数
func make(Type, size IntegerType) Type
内建函数make分配并初始化一个类型为切片、映射、或通道的对象。其第一个实参为类型,而非值。make的返回类型与其参数相同,而非指向它的指针。其具体结果取决于具体的类型:
切片:size指定了其长度。该切片的容量等于其长度。切片支持第二个整数实参可用来指定不同的容量;
它必须不小于其长度,因此 make([]int, 0, 10) 会分配一个长度为0,容量为10的切片。
映射:初始分配的创建取决于size,但产生的映射长度为0。size可以省略,这种情况下就会分配一个
小的起始大小。
通道:通道的缓存根据指定的缓存容量初始化。若 size为零或被省略,该信道即为无缓存的。
map 的使用方式
package main
import (
"fmt"
)
func main(){
//方式1
//声明
var cities1 map[string]string
//使用make 初始化
cities1= make(map[string]string)
cities1["a"]= "golang"
//方式2声明并初始化
var cities2 = make(map[string]string)
cities2["q"]="你好"
//方式3 声明初始化并赋值(make没有明确写,但底层给make了)
var cities3 map[string]string= map[string]string{"node1":"晨曦"}
cities3["node2"]= "上海"
fmt.Println("方式1",cities1)
fmt.Println("方式2",cities2)
fmt.Println("方式3",cities3)
cities4 := map[string]string{
"悟空":"金箍棒",
"八戒":"九齿钉耙",
"沙和尚":"降魔杖",
"哪吒":"火尖枪",
}
fmt.Println("方式4",cities4)
}
// PS D:\golang\goproject\src\src01\go_code\src> go run chapter08\deom02\main.go
// 方式1 map[a:golang]
// 方式2 map[q:你好]
// 方式3 map[node1:晨曦 node2:上海]
// 方式4 map[八戒:九齿钉耙 哪吒:火尖枪 悟空:金箍棒 沙和尚:降魔杖]
示例1
package main
import (
"fmt"
)
func main(){
//方式1
//声明
var cities1 map[string]string
//使用make 初始化
cities1= make(map[string]string)
cities1["a"]= "golang"
//方式2声明并初始化
var cities2 = make(map[string]string)
cities2["q"]="你好"
//方式3 声明初始化并赋值(make没有明确写,但底层给make了)
var cities3 map[string]string= map[string]string{"node1":"晨曦"}
cities3["node2"]= "上海"
fmt.Println("方式1",cities1)
fmt.Println("方式2",cities2)
fmt.Println("方式3",cities3)
cities4 := map[string]string{
"悟空":"金箍棒",
"八戒":"九齿钉耙",
"沙和尚":"降魔杖",
"哪吒":"火尖枪",
}
fmt.Println("方式4",cities4)
cities5 := make(map[string]map[string]string)
//cities5= make(map[string]map[string]string)
cities5["学生1"]= make(map[string]string)//这句话不能少
cities5["学生2"]= make(map[string]string)
cities5["学生3"]= make(map[string]string)
cities5["学生1"]["名字"]= "tom"
cities5["学生1"]["性别"]= "男"
cities5["学生1"]["地址"]= "胡同"
cities5["学生2"]["名字"]= "丽娜"
cities5["学生2"]["性别"]= "女"
cities5["学生2"]["地址"]= "天通苑"
cities5["学生3"]["名字"]= "杰克"
cities5["学生3"]["性别"]= "男"
cities5["学生3"]["地址"]= "青年汇"
fmt.Println(cities5["学生3"])
}
// PS D:\golang\goproject\src\src01\go_code\src> go run chapter08\deom02\main.go
// 方式1 map[a:golang]
// 方式2 map[q:你好]
// 方式3 map[node1:晨曦 node2:上海]
// 方式4 map[八戒:九齿钉耙 哪吒:火尖枪 悟空:金箍棒 沙和尚:降魔杖]
// map[名字:杰克 地址:青年汇 性别:男]
map 的增删改成操作
package main
import (
"fmt"
)
func main(){
a := make(map[string]string)
a["a1"]= "阿库"
a["a2"]= "小米"
a["a3"]= "小鹿"
a["a4"]= "小鹏"
fmt.Println("修改前打印",a)
//修改a[a2的值]
a["a2"]="小白"
fmt.Println("修改后打印",a["a2"])
fmt.Println("修改打印",a)
//增加一个
a["w1"]= "奶茶"
fmt.Println("增加新值打印",a)
//删除一个值
delete(a,"a3")
fmt.Println("删除后打印",a)
}
// 执行结果
// PS D:\golang\goproject\src\src01\go_code\src> go run chapter08\deom03\main.go
// 修改前打印 map[a1:阿库 a2:小米 a3:小鹿 a4:小鹏]
// 修改后打印 小白
// 修改打印 map[a1:阿库 a2:小白 a3:小鹿 a4:小鹏]
// 增加新值打印 map[a1:阿库 a2:小白 a3:小鹿 a4:小鹏 w1:奶茶]
// 删除后打印 map[a1:阿库 a2:小白 a4:小鹏 w1:奶茶]
delete 删除操作
func delete(m map[Type]Type1, key Type) 内建函数delete按照指定的键将元素从映射中删除。若m为nil或无此元素,delete不进行操作。
细节说明
1)如果我们要删除map 的所有key,没有一个专门的方法一次性删除,可以遍历删除
package main
import (
"fmt"
)
func main(){
a := make(map[string]string)
a["a1"]= "阿库"
a["a2"]= "小米"
a["a3"]= "小鹿"
a["a4"]= "小鹏"
fmt.Println("修改前打印",a)
//修改a[a2的值]
a["a2"]="小白"
fmt.Println("修改后打印",a["a2"])
fmt.Println("修改打印",a)
//增加一个
a["w1"]= "奶茶"
fmt.Println("增加新值打印",a)
//删除一个值
delete(a,"a3")
fmt.Println("删除后打印",a)
// 遍历整个map集合
fmt.Println("变量整个map")
for i,v := range a{
fmt.Println(i,v)
}
//遍历所以value
//遍历整个map 集合的key 与value
fmt.Println("遍历整个map 集合的key 与value")
for _,v := range a{
fmt.Println(v)
}
// 希望删除所有key;遍历逐一删除;遍历键时可以使用下面方法
fmt.Println("遍历删除整个集合")
for k := range a{
delete(a,k)
}
fmt.Println("清空后打印",a)
}
// 执行结果
// PS D:\golang\goproject\src\src01\go_code\src> go run chapter08\deom03\main.go
// 修改前打印 map[a1:阿库 a2:小米 a3:小鹿 a4:小鹏]
// 修改后打印 小白
// 修改打印 map[a1:阿库 a2:小白 a3:小鹿 a4:小鹏]
// 增加新值打印 map[a1:阿库 a2:小白 a3:小鹿 a4:小鹏 w1:奶茶]
// 删除后打印 map[a1:阿库 a2:小白 a4:小鹏 w1:奶茶]
// 变量整个map
// a1 阿库
// a2 小白
// a4 小鹏
// w1 奶茶
// 遍历整个map 集合的key 与value
// 小鹏
// 奶茶
// 阿库
// 小白
// 遍历删除整个集合
// 清空后打印 map[]
2)或者map= make(...),make一个新的,让原来的成为垃圾,被gc回收
package main
import (
"fmt"
)
func main(){
a := make(map[string]string)
a["a1"]= "阿库"
a["a2"]= "小米"
a["a3"]= "小鹿"
a["a4"]= "小鹏"
fmt.Println("修改前打印",a)
//修改a[a2的值]
a["a2"]="小白"
fmt.Println("修改后打印",a["a2"])
fmt.Println("修改打印",a)
//增加一个
a["w1"]= "奶茶"
fmt.Println("增加新值打印",a)
//删除一个值
delete(a,"a3")
fmt.Println("删除后打印",a)
fmt.Println("删除整个集合",a)
a = map[string]string{}
fmt.Println("清空后打印",a)
}
// 执行结果
// PS D:\golang\goproject\src\src01\go_code\src> go run chapter08\deom03\main.go
// 修改前打印 map[a1:阿库 a2:小米 a3:小鹿 a4:小鹏]
// 修改后打印 小白
// 修改打印 map[a1:阿库 a2:小白 a3:小鹿 a4:小鹏]
// 增加新值打印 map[a1:阿库 a2:小白 a3:小鹿 a4:小鹏 w1:奶茶]
// 删除后打印 map[a1:阿库 a2:小白 a4:小鹏 w1:奶茶]
// 删除整个集合 map[a1:阿库 a2:小白 a4:小鹏 w1:奶茶]
// 清空后打印 map[]
查找
package main
import (
"fmt"
)
func main(){
a := make(map[string]string)
a["a1"]= "阿库"
a["a2"]= "小米"
a["a3"]= "小鹿"
a["a4"]= "小鹏"
// 查找
val,ok := a["a1"]
if ok{
fmt.Println("有这个a1 key;值为",val)
}else {
fmt.Println("没有有这个a1 key;值为")
}
}
// 执行结果
// PS D:\golang\goproject\src\src01\go_code\src> go run chapter08\deom03\main.go
// 有这个a1 key;值为 阿库
遍历
package main
import (
"fmt"
)
func main(){
a := make(map[string]string)
a["a1"]= "阿库"
a["a2"]= "小米"
a["a3"]= "小鹿"
a["a4"]= "小鹏"
//遍历k
fmt.Println("遍历k")
for k:= range a{
fmt.Println(k)
}
//遍历整个几个
fmt.Println("遍历整个集合")
for v,k := range a{
fmt.Println(v,k)
}
}
// 执行结果
// PS D:\golang\goproject\src\src01\go_code\src> go run chapter08\deom04\main.go
// 遍历k
// a1
// a2
// a3
// a4
// 遍历整个集合
// a1 阿库
// a2 小米
// a3 小鹿
// a4 小鹏
示例2
package main
import (
"fmt"
)
func main(){
cities5 := make(map[string]map[string]string)
//cities5= make(map[string]map[string]string)
cities5["学生1"]= make(map[string]string)//这句话不能少
cities5["学生2"]= make(map[string]string)
cities5["学生3"]= make(map[string]string)
cities5["学生1"]["名字"]= "tom"
cities5["学生1"]["性别"]= "男"
cities5["学生1"]["地址"]= "胡同"
cities5["学生2"]["名字"]= "丽娜"
cities5["学生2"]["性别"]= "女"
cities5["学生2"]["地址"]= "天通苑"
cities5["学生3"]["名字"]= "杰克"
cities5["学生3"]["性别"]= "男"
cities5["学生3"]["地址"]= "青年汇"
for x := range cities5{
for i,v := range cities5[x]{
fmt.Printf("学生%v的%v是%v\n",x,i,v)
}
}
}
// 执行结果
// PS D:\golang\goproject\src\src01\go_code\src> go run chapter08\deom04\main.go
// 学生学生1的名字是tom
// 学生学生1的性别是男
// 学生学生1的地址是胡同
// 学生学生2的名字是丽娜
// 学生学生2的性别是女
// 学生学生2的地址是天通苑
// 学生学生3的性别是男
// 学生学生3的地址是青年汇
// 学生学生3的名字是杰克
统计长度
数组:v中元素的数量 数组指针:*v中元素的数量(v为nil时panic) 切片、映射:v中元素的数量;若v为nil,len(v)即为零 字符串:v中字节的数量 通道:通道缓存中队列(未读取)元素的数量;若v为 nil,len(v)即为零
package main
import (
"fmt"
)
func main(){
a := make(map[string]string)
a["a1"]= "阿库"
a["a2"]= "小米"
a["a3"]= "小鹿"
a["a4"]= "小鹏"
fmt.Println("map a 的长度",len(a))
}
// 执行结果
// PS D:\golang\goproject\src\src01\go_code\src> go run chapter08\deom04\main.go
// map a 的长度 4
map切片
切片的基本数组如果是map 。称为slice of map,map切片,这样使用则map个数就可以动态变化了
package main
import (
"fmt"
)
func main(){
var mosters []map[string]string
mosters = make([]map[string]string,2)//初始化切片
if mosters[0]== nil{
mosters[0]= make(map[string]string)
mosters[0]["名字"]="牛魔王"
mosters[0]["年龄"]="1600"
}
if mosters[1]== nil{
mosters[1]= make(map[string]string)
mosters[1]["名字"]="牛魔王"
mosters[1]["年龄"]="1600"
}
a := map[string]string{
"name": "黑熊怪",
"age" : "1400",
}
mosters= append(mosters, a)
fmt.Println(mosters)
}
// 执行结果
// PS D:\golang\goproject\src\src01\go_code\src> go run chapter08\deom05\main.go
// [map[名字:牛魔王 年龄:1600] map[名字:牛魔王 年龄:1600] map[age:1400 name:黑熊怪]]
map的排序
1)golang中没有一个专门的方法针对map的key 进行排序
2)golang 中map 默认是无序的,注意也不是按照添加顺序存放的,每次遍历得到的输出可能不一样
3)golang 中map 的排序,是先将key 进行排序,然后根据key的值遍历
示例
package main
import (
"fmt"
"sort"
)
func main(){
map1 :=make(map[int]int)
map1[0]=0
map1[1]=1
map1[67]=9
map1[5]=98
fmt.Println(map1)
//如何安装map的key顺序进行排序输出
//1. 先将map的key 放到切片中
//2.对切片进行排序
//3遍历切片。按照k
keys := []int{}
for k := range map1{
keys=append(keys,k)
}
fmt.Println(keys)
fmt.Println("排序前打印map")
for i,v := range map1{
fmt.Printf("排序前map[%v]=%v ",i,v)
}
fmt.Println()
// 排序
sort.Ints(keys)
fmt.Println(keys)
//排序打印map
for _,v := range keys{
fmt.Printf("排序后map[%v]=%v ",v,map1[v])
}
}
// 执行结果
// PS D:\golang\goproject\src\src01\go_code\src> go run chapter08\deom05\main.go
// map[0:0 1:1 5:98 67:9]
// [0 1 67 5]
// 排序前打印map
// 排序前map[67]=9 排序前map[5]=98 排序前map[0]=0 排序前map[1]=1
// [0 1 5 67]
// 排序后map[0]=0 排序后map[1]=1 排序后map[5]=98 排序后map[67]=9
// PS D:\golang\goproject\src\src01\go_code\src> go run chapter08\deom06\main.go
// map[0:0 1:1 5:98 67:9]
// [5 0 1 67]
// 排序前打印map
// 排序前map[0]=0 排序前map[1]=1 排序前map[67]=9 排序前map[5]=98
// [0 1 5 67]
// 排序后map[0]=0 排序后map[1]=1 排序后map[5]=98 排序后map[67]=9
// PS D:\golang\goproject\src\src01\go_code\src> go run chapter08\deom06\main.go
// map[0:0 1:1 5:98 67:9]
// [0 1 67 5]
// 排序前打印map
// 排序前map[1]=1 排序前map[67]=9 排序前map[5]=98 排序前map[0]=0
// [0 1 5 67]
// 排序后map[0]=0 排序后map[1]=1 排序后map[5]=98 排序后map[67]=9
map使用细节
1)map 是引用数据类型,遵守引用类型传递的机制在一个函数接收map,修改后,会直接修改原来的map
package main
import "fmt"
func modify(map1 map[int]int){
map1[10] =900
}
func main(){
map1 := make(map[int]int)
map1[10] = 20
map1[29] = 89
fmt.Println("map1=",map1)
modify(map1)
fmt.Println("修改后map=",map1)
}
// 执行结果
// PS D:\golang\goproject\src\src01\go_code\src> go run chapter08\deom05\main.go
// map1= map[10:20 29:89]
// 修改后map= map[10:900 29:89]
2)map 的容量达到后,在想map增加元素,会自动扩容,并不会panic ,也就是说map能动态的增长键值对(key-value)
package main
import "fmt"
func modify(map1 map[int]int){
map1[10] =900
}
func main(){
map1 := make(map[int]int,2)
map1[10] = 20
map1[29] = 89
fmt.Println("map1=",map1)
modify(map1)
fmt.Println("修改后map=",map1)
map1[43]= 98
fmt.Println("增加一个键值对后map=",map1)
}
// 执行结果
// PS D:\golang\goproject\src\src01\go_code\src> go run chapter08\deom05\main.go
// map1= map[10:20 29:89]
// 修改后map= map[10:900 29:89]
// 修改后map= map[10:900 29:89 43:98]
3)map 的value也经常使用struct类型,更适合管理更复杂的数据结构(例如value 是一个map更好),比如value为student 结构体
package main
import "fmt"
func modify(map1 map[int]int){
map1[10] =900
}
type sty struct{
name string
age int
add string
}
func main(){
students := make(map[string]sty,10)
//创建
stu1 := sty{"tom", 29, "天通苑"}
stu2 := sty{"lina", 29, "胡同"}
stu3 := sty{"小杰", 29, "青年汇"}
students["cx"] = stu1
students["cw"] = stu2
students["no2"] = stu3
fmt.Println(students)
}
// 执行结果
// PS D:\golang\goproject\src\src01\go_code\src> go run chapter08\deom05\main.go
// map[cw:{lina 29 胡同} cx:{tom 29 天通苑} no2:{小杰 29 青年汇}]
遍历
package main
import "fmt"
func modify(map1 map[int]int){
map1[10] =900
}
type sty struct{
name string
age int
add string
}
func main(){
students := make(map[string]sty,10)
//创建
stu1 := sty{"tom", 29, "天通苑"}
stu2 := sty{"lina", 29, "胡同"}
stu3 := sty{"小杰", 29, "青年汇"}
students["cx"] = stu1
students["cw"] = stu2
students["no2"] = stu3
fmt.Println(students)
for i,v := range students{
fmt.Printf("学生编号%v\n",i)
fmt.Printf("学生名字%v\n",v.name)
fmt.Printf("学生住址%v\n",v.add)
fmt.Printf("学生年龄%v\n",v.age)
}
}
// 执行结果
// PS D:\golang\goproject\src\src01\go_code\src> go run chapter08\deom05\main.go
// map[cw:{lina 29 胡同} cx:{tom 29 天通苑} no2:{小杰 29 青年汇}]
// 学生编号cx
// 学生名字tom
// 学生住址天通苑
// 学生年龄29
// 学生编号cw
// 学生名字lina
// 学生住址胡同
// 学生年龄29
// 学生编号no2
// 学生名字小杰
// 学生住址青年汇
// 学生年龄29
练习
package main
import "fmt"
func modify(map1 map[int]int){
map1[10] =900
}
type sty struct{
name string
age int
add string
}
func test(a map[string]map[string]string,name string){
if a[name] !=nil { // 判断是map否存在某key
//有用户
a[name]["pws"] = "888888"
} else {
//fmt.Println("输入用户名")
a[name] = make(map[string]string)
a[name]["pwd"]= "88888"
a[name]["昵称"]= "昵称"+name
}
}
func main(){
t := make(map[string]map[string]string)
t["go"] = make(map[string]string)
t["go"]["pwd"]="999999"
t["go"]["昵称"]="Golang"
test(t,"tom")
test(t,"dagu")
test(t,"go")
fmt.Println(t)
}
// 执行结果
// PS D:\golang\goproject\src\src01\go_code\src> go run chapter08\deom05\main.go
// map[dagu:map[pwd:88888 昵称:昵称dagu] go:map[pwd:999999 pws:888888 昵称:Golang] tom:map[pwd:88888 昵称:昵称tom]]

浙公网安备 33010602011771号