map是一种key-value的数据结构,类似于Java中的Map集合。map 的 key-value 是无序的,也不是按照添加顺序存放的,你每次遍历得到的结果顺序可能都不一样,且key不能重复,如果重复了就以最新的 key 为准。
1. map 的定义
1.1 基本语法
var 变量名称 map[key数据类型]value数据类型
key的数据类型: bool 、数字、string、指针、管道、接口、结构体、数组。但是通常使用int和string 类型作为key。key不能是切片、map 和 函数,因为它们没法用==来判断。value可以是符合 golang 语法规则的数据类型。
1.2 map 的声明示例
map在声明后不会分配内存,需要先使用 make 函数初始化分配内存以后才能赋值和使用
var a map[string]string
var b map[string]int
var c map[int]string
var d map[string]map[string]string // 相当于Java中 Map<String,Map<String,String>>
1.2.1 声明方式一
package main
import "fmt"
func main() {
var m map[string]string = make(map[string]string,10)
m["1"] = "A"
m["2"] = "B"
// map[1:A 2:B]
fmt.Println(m)
}
1.2.2 声明方式二
package main
import "fmt"
func main() {
cityMap := map[string]string{
"a" : "北京",
"b" : "上海",
"c" : "西安",
}
cityMap["d"] = "商洛"
// map[a:北京 b:上海 c:西安 d:商洛]
fmt.Println(cityMap)
}
2. map的增删改查操作
2.1 新增修改
map[key] = value :如果key不存在就是新增,如果key存在就是修改
package main
import "fmt"
func main() {
cityMap := map[string]string{
"a" : "北京",
"b" : "上海",
"c" : "西安",
}
cityMap["d"] = "商洛"
cityMap["a"] = "长沙"
// map[a:长沙 b:上海 c:西安 d:商洛]
fmt.Println(cityMap)
}
2.2 删除元素
func delete(m map[Type]Type1, key Type)
内置函数delete按照指定的键将元素从map中删除。若m为nil或无此元素,delete不进行操作。
2.3 查找元素
package main
import "fmt"
func main() {
cityMap := map[string]string{
"a" : "北京",
"b" : "上海",
"c" : "西安",
}
cityMap["d"] = "商洛"
cityMap["a"] = "长沙"
// map[a:长沙 b:上海 c:西安 d:商洛]
fmt.Println(cityMap)
// 查找map中的元素
val,res := cityMap["a"]
if res {
fmt.Printf("key存在,res=%v,val=%v\n", res, val)
} else {
fmt.Printf("key不存在,res=%v,val=%v\n", res, val)
}
}
2.3 遍历和长度
- map 遍历使用
for-range - map 长度使用内置函数
len
2.4 map排序
golang的map的排序,是先将key进行排序,然后遍历key获取value
- (1)将 map 的 key 放入到 数组切片中
- (2)对数组切片排序
- (3)遍历数组切片,然后输出 map 值
package main
import "fmt"
import "sort"
func main() {
m := map[int]string {
100 : "纽约",
23 : "伦敦",
34 : "香港",
1 : "西安",
5 : "伊犁",
}
var keys []int
for key,_ := range m {
keys = append(keys, key)
}
// [100 23 34 1 5]
fmt.Println(keys)
sort.Ints(keys)
// [1 5 23 34 100]
fmt.Println(keys)
for _,v := range keys {
fmt.Printf("key = %v, val = %v\n",v, m[v])
}
}
3. map 切片
数据类型是map的切片,我们称为map切片,这样map数据就可以动态变化了
var m []map[int]int
package main
import "fmt"
func main() {
// map切片声明方,可以理解成 Java 中的 List<Map<String,String>>,初始化长度为 2
var mapSlice []map[string]string = make([]map[string]string, 2)
if(mapSlice[0] == nil) {
mapSlice[0] = map[string]string {
"cityId" : "2",
"cityName" : "伦敦",
}
}
if(mapSlice[1] == nil) {
mapSlice[1] = make(map[string]string, 2)
mapSlice[1]["cityId"] = "3"
mapSlice[1]["cityName"] = "香港"
}
// 声明一个 map
map2 := map[string]string {
"cityId" : "1",
"cityName" : "西安",
}
mapSlice = append(mapSlice, map2)
// [map[cityId:1 cityName:西安] map[cityId:3 cityName:香港] map[cityId:1 cityName:西安]]
fmt.Println(mapSlice)
}
4. map使用细节
- map 是引用类型,遵守引用类型传递机制,当一个函数接收map参数后,这个参数被修改,会直接修改原来的 map
- map 能动态扩容,这点和数组是有区别的,数组一旦声明长度就是固定的,不能动态变化