内容目录
- map
内容详细
map定义
- map是一种无序的基于
key-value
的数据结构,Go语言中的map是引用类型,必须初始化才能使用。 - GO语言中map的定义语法:
map[KeyType]ValueType
KeyType:表示键的类型。
ValueType:表示键对应的值的类型。
- map类型的变量默认初始值为nil,需要使用make()函数来分配内存。
- 其中cap表示map的容量,该参数虽然不是必须的,但是应该在初始化map的时候就为其指定一个合适的容量。
make(map[KeyType]ValueType, [cap])
map的基本使用
- map中的数据都是成对出现的
// 声明完后,再初始化
func main() {
// 声明map类型,但是没有初始化,a就是初始值nil
var a map[string]int
fmt.Println(a == nil) // true
// map的初始化
a = make(map[string]int, 8)
fmt.Println(a == nil) // false
// map中添加键值对
a["沙河娜扎"] = 100
a["沙河小王子"] = 200
fmt.Printf("a:%#v \n", a)
fmt.Printf("type:%T \n", a)
}
// a:map[string]int{"沙河娜扎":100, "沙河小王子":200}
// type:map[string]int
- map支持声明的时候就填充元素
func main() {
// 声明map的同时完成初始化
b := map[int]bool{
1:true,
2:false,
}
fmt.Printf("b:%#v \n",b)
fmt.Printf("type:%T \n",b)
}
// b:map[int]bool{1:true, 2:false}
// type:map[int]bool
判断某个键是否存在
- Go语言中有个判断map中键是否存在的特殊写法
value, ok := map[key]
value:表示找到key后,返回所对应的value,如找不到,就返回此map存储数据类型的空值
ok:表示找到就返回true,否则返回false
func main() {
// 判断某个键是否存在于map
var scoreMap = make(map[string]int, 8)
scoreMap["知春路娜扎"] = 100
scoreMap["知春路小王子"] = 250
// 判断 张三 是否存在 scoreMap中
value, ok := scoreMap["张三"]
fmt.Println(value, ok)
if ok {
fmt.Println("张三存在scoreMap中", value)
} else {
fmt.Println("查无此人")
}
}
// 0 false
// 查无此人
map遍历
- Go语言中使用
for range
遍历map。 - 注意: 遍历map时的元素顺序与添加键值对的顺序无关。
func main() {
var scoreMap = make(map[string]int, 8)
scoreMap["知春路娜扎"] = 100
scoreMap["知春路小王子"] = 250
// 遍历key和value
for key,val := range scoreMap{
fmt.Println(key,val)
}
// 只遍历key
for key := range scoreMap{
fmt.Println(key)
}
// 只遍历value
for _,val := range scoreMap{
fmt.Println(val)
}
}
删除map元素(键值对)
- 使用delete方法删除指定键值对
func main() {
var scoreMap = make(map[string]int, 8)
scoreMap["知春路娜扎"] = 100
scoreMap["知春路小王子"] = 250
// 删除map中指定的键值对
delete(scoreMap,"知春路小王子")
}
按照指定顺序排序遍历map
- 使用切片中的sort方法进行排序
import (
"fmt"
"math/rand"
"sort"
)
func main() {
// 初始化一个容量为100的map
var scoreMap = make(map[string]int, 100)
// 添加50个键值对
for i :=0;i<50;i++{
key := fmt.Sprintf("stu%02d",i)
value := rand.Intn(100) // 0-99的随机数
scoreMap[key] = value
}
// 按照从小到大的顺序遍历
// 1.先取出所有的key存放到切片中
keys := make([]string, 0, 100)
for k := range scoreMap{
keys = append(keys, k)
}
// 2.对key进行排序
sort.Strings(keys) // 对keys进行排序
// 3.按照排序后的key对scoreMap进行排序
for _,key := range keys{
fmt.Println(key, scoreMap[key])
}
}
元素为map类型的切片
- map可以嵌套进切片中
- 注意:切片要进行初始化才能嵌套map,而map作为切片的元素,也需要进行初始化才能存储键值对
- 未初始化map,切片中的元素就等于nil
func main() {
var mapSlice = make([]map[string]int,8,8) // 支持完成了切片的初始化
fmt.Println(mapSlice[0] == nil) // true
// 还需要完成内部map元素的初始化
mapSlice[0] = make(map[string]int,8) //完成map的初始化
mapSlice[0]["沙河"] = 100
mapSlice[0]["清河"] = 150
mapSlice[1] = make(map[string]int,8) //完成map的初始化
mapSlice[1]["海淀"] = 200
mapSlice[1]["望京"] = 250
fmt.Println(mapSlice)
}
// true
// [map[沙河:100 清河:100] map[望京:250 海淀:200] map[]]
值为切片的map
- 切片也可以作为map键值对中值的存在
- 注意:map初始化后,值为切片的也需要初始化
func main() {
var sliceMap = make(map[string][]int,3) // 只完成了map的初始化
v,ok := sliceMap["中国"]
if ok{
fmt.Println(v)
}else {
// 如果sliceMap没有“中国”指定的键
sliceMap["中国"] = make([]int,8) // 完成对切片的初始化
sliceMap["中国"][0] = 100
sliceMap["中国"][1] = 200
sliceMap["中国"][2] = 300
}
sliceMap["我爱"] = make([]int,8) // 对键值对中值为切片的初始化
sliceMap["我爱"][0] = 500
sliceMap["我爱"][1] = 300
sliceMap["我爱"][2] = 100
// 遍历sliceMap
for k,v :=range sliceMap{
fmt.Println(k,v)
}
}
// 中国 [100 200 300 0 0 0 0 0]
// 我爱 [500 300 100 0 0 0 0 0]
例:统计一个字符串中重复单词的次数
func main() {
// 统计一个字符串中每个单词出现的次数
// "how do you do"中每个单词出现的次数
// 1.定义一个map[string]int,其中string表示单词,int表示次数
s := "how do you do"
var wordMap = make(map[string]int, 8)
// 2.字符串中都有哪些单词
words := strings.Split(s," ")
// 3.遍历单词做统计
for _,word := range words{
val,ok := wordMap[word]
if ok{
// 判断遍历出的值存在于words切片中
wordMap[word] = val + 1
}else{
wordMap[word] = 1
}
}
for k,v :=range wordMap{
fmt.Println(k,v)
}
}