map
-
类似其他语言中的哈希表或者字典,以key-value形式存储数据
-
key必须是支持 == 或 != 比较运算的类型,不可以是函数,map或slice
-
Map查找比线性搜索快很多,但比使用索引访问数据的类型慢100倍
-
Map使用make()创建,支持 := 这种简写方式
-
make([keyType]valueType,cap), cap表示容量,可以省略
-
超出容量时会自动扩容,但尽量提供一个合理的初始值
-
使用 len() 获取元素个数
-
键值对不存在时自动添加,使用delete()删除某键值对
-
使用 for range 对 map和slice进行迭代操作
map的初始化
//完成map的初始化
var m map[int]string //[key类型]value类型
m = map[int]string{}
fmt.Println(m)
//第二种map初始化的方式
var m2 map[int]string = make(map[int]string)
fmt.Println(m2)
//简洁的初始化定义方式
m3 := make(map[int]string)
fmt.Println(m3)
运行结果:
map的简单使用
m := make(map[int]string)
//给map中键值对赋值
m[1] = "OK"
a := m[1]
fmt.Println(a)
m[2] = "OK"
delete(m, 2)//删除操作
b := m[2]
fmt.Println(b)
运行结果:
for rangge
map复杂操作
map类型的value
//map类型的value,每个map在使用的时候都要进行初始化
var m map[int]map[int]string
m = make(map[int]map[int]string) //只是将外层的map初始化,value就是内层的map并没有初始化
m[1] = make(map[int]string) //内层的初始化,就是第二层map的初始化
m[1][1] = "OK"
a := m[1][1]
fmt.Println(a)
b, ok := m[2][1] //只有一个返回值的时候返回的是value,有两个返回值的时候,第二个返回的是这个键值对是否存在,为bool类型
fmt.Println(b, ok)
if !ok { //如果键值对不存在
m[2] = make(map[int]string) //初始化
}
m[2][1] = "GOOD"
b, ok = m[2][1]
fmt.Println(b, ok)
运行结果:
迭代操作
//slice 和map都可以进行迭代操作
//for range 是和java中foreach类似,但是更高级;下面是对slice进行的操作
// for i, v := range slice { //返回两个值i和v:i是slice相对应的索引,为int型相当于计数器 ;v是slice中存储值,拿的值是slice的拷贝,任何的修改不会影响值的本身
// //slice[i] 可以通过索引的方式可以进行值本身的操作
// }
// //下面是对map进行的操作
// for k, v := range map{ //返回的是键值对
// //map[k] 同样可以通过k进行map的操作
// }
下面是实例
sm := make([]map[int]string, 5)
for _, v := range sm {
v = make(map[int]string, 1)
v[1] = "OK"
fmt.Println(v)
}
fmt.Println(sm)
运行结果:
之所以map为空,是因为拿的是map的拷贝,并不会对map造成更改。
下面是直接操作:
sm := make([]map[int]string, 5)
for i := range sm {
sm[i] = make(map[int]string, 1)
sm[i][1] = "OK"
fmt.Println(sm[i])
}
fmt.Println(sm)
运行结果:
对map间接排序
m := map[int]string{1: "a", 2: "b", 3: "c", 4: "d", 5: "e"} //定义map
s := make([]int, len(m)) //定义slice
//根据map性质,完成key的排序就是完成value的排序
i := 0
for k, _ := range m {
s[i] = k
i++
}
fmt.Println(s)
//由于map的无序性,每次打印都是无序的
sort.Ints(s) //进行排序
fmt.Println(s)
运行结果: