内容目录

  • 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)
	}
}