8 Map
8.1 声明、初始化和make
声明
var mapName map[keytype]valuetype
//key为int类型 value为string类型的map
var x map[int]string
初始化
var map = make(map[int]string)
//简写 相当于 map := map[int]string{}
map := make(map[int]string)
注意:不要使用new ,永远用make构造map
如果使用new()分配了一个引用对象,会获得一个空引用指针,相当于声明了一个未初始化的变量并取了它的地址
z := new(map[int]string)
z[0] = "dafads"
//Invalid operation: 'z[0]' (type '*map[int]string' does not support indexing)
map的值可以是任意类型
//值得类型 为函数
a := map[int]func() int{
0: func() int { return 0 },
1: func() int { return 1 },
2: func() int { return 2 },
}
//值为函数的地址
fmt.Println(a[0])
fmt.Println(a[1])
fmt.Println(a[2])
//切片作为value
b := map[int][]int{
0: make([]int, 10),
1: make([]int, 5),
2: make([]int, 6),
}
fmt.Println(b[0])
fmt.Println(b[1])
fmt.Println(b[2])
map容量
map根据key-value动态得伸缩,不存在固定长度或者最大限制,可以初始化时标明map的初始容量
map1 := make(map[int]string,100)
当map增长到容量上限时,如果再增加新的key-value,map的大小会自动加1。出于性能考虑,对于大的map或会快速扩张的map,需要标明容量。
8.2 测试键值对是否存在及删除元素
_,ok := map[key]//如果key存在 ok == true 否则ok == false
b := map[int][]int{
0: make([]int, 10),
1: make([]int, 5),
2: make([]int, 6),
}
_, ok := b[4]
if ok {
fmt.Println(b[4])
} else {
fmt.Println("b中不存在key = 4的键值对")
}
从map中删除指定key 如果key不存在,该操作不会产生错误
delete(map,key)
8.3 for-range配套用法
for key,value := range map{
}
注意:map不是按照key的顺序排列的,也不是按照value的序排列的
b := map[int][]int{
0: make([]int, 10),
1: make([]int, 5),
2: make([]int, 6),
}
for key, value := range b {
fmt.Printf("key: %d,value: %d\n", key, value)
}
key: 0,value: [0 0 0 0 0 0 0 0 0 0]
key: 1,value: [0 0 0 0 0]
key: 2,value: [0 0 0 0 0 0]
8.4 map类型的切片
如果我们想获取一个map类型的切片,必须使用两次make()函数,第一次分配切片,第二次分配切片中每个map元素
//创建切片及相关数组 长度为5 数组类型为map[int]string
d := make([]map[int]string, 5)
for i := range d {
//切片的元素为map类型 这里在初始化map key -> int value -> string capacity -> 1
d[i] = make(map[int]string, 1)
//key 为 1 value 为 "xxx"
d[i][1] = "xxx"
}
8.5 map的排序
map默认无序,想为map排序,需要将key或value拷贝到一个切片,再对切片排序
xx := map[string]int{"bind": 1, "must": 2, "query": 3, "person": 4, "array": 5, "zoo": 6}
fmt.Println("xx未排序前")
for key, value := range xx {
fmt.Printf("key: %s,value: %d\n", key, value)
}
//创建一个元素为string的切片 并创建相关数组 长度为map类型xx的长度
slice := make([]string, len(xx))
i := 0
//将xx中的key放入slice中作为元素
for k, _ := range xx {
slice[i] = k
i++
}
//sort包下的strings对slice元素排序
sort.Strings(slice)
fmt.Println("xx排序后")
for _, k := range slice {
fmt.Printf("key: %v, value: %v\n", k, xx[k])
}
xx未排序前
key: bind,value: 1
key: must,value: 2
key: query,value: 3
key: person,value: 4
key: array,value: 5
key: zoo,value: 6
xx排序后
key: array, value: 5
key: bind, value: 1
key: must, value: 2
key: person, value: 4
key: query, value: 3
key: zoo, value: 6
8.6 将map的键值对调
map1 := map[string]int{"aa": 1, "2131b": 2, "cc": 3, "add": 4, "dafa": 5}
map2 := make(map[int]string, len(map1))
for key, value := range map1 {
map2[value] = key
}
fmt.Println()
for key, value := range map2 {
fmt.Printf("key: %d,value: %s\n", key, value)
}