• 07-Go语言中map数据结构用法


    map函数的原理

    map是key-value结构的数据类型,类似于其他语言中的hash table,dict等

    key必须是可hash的值,是一个确定的值(key的值不能设置了之后又发生了改变)

    map存储的时候 hash(key) --> 固定的值 --> 把value放到对应的位置保存

    map[key] : hash(key) --> 得到值 --> 取对应的value

    map定义

    GO语言中map的定义语法如下:

    map[KeyType]ValueType
    
    • 1

    其中,

    • KeyType:表示键的类型。
    • ValueType:表示键对应的值的类型。

    map类型的变量默认初始值为nil,需要使用make()函数初始化分配内存。语法为:

    make(map[KeyType]ValueType,[cap])
    
    • 1

    其中cap表示map的容量,该参数虽然不是必须的,但是我们应该在初始化map的时候为其指定一个合适的容量。

    map初始化

    map初始化的方法有字面量初始化,make()函数初始化。

    字面量初始化:

    //字面量初始化
    func f18() {
    	var m map[string]int
    
    	fmt.Println(m == nil) // true。map未初始化,值为nil
    
    	m1 := map[string]string{
    		"username": "王磊",
    		"password": "1234", //花括号换行此处必须加逗号
    	}
    	fmt.Printf("%#v\n", m1) //
    }
    
    //运行结果:
    true
    map[string]string{"password":"1234", "username":"王磊"}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    make()函数初始化:

    //make函数初始化
    func f19() {
    	m2 := make(map[string]int) //只要初始化就可以赋值
    	fmt.Println(m2 == nil)     //false,因为map已经初始化
    
    	m2["wanglei"] = 120 //设置值
    	fmt.Println(m2)
    
    	weight := m2["wanglei"] //取值
    	fmt.Println(weight)
    
    }
    
    //运行结果:
    false
    map[wanglei:120]
    120
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    判断某个键是否存在

    GO语言中有个判断map中键是否存在的特殊写法,格式如下:

    value,ok := map[key]
    
    • 1

    举个例子:

    //判断key是否存在
    func f20() {
    	m3 := make(map[string]int)
    
    	m3["wanglei"] = 120
    	m3["jack"] = 200
    	// v,ok取值;OK是一个变量名,只不过大家约定俗成在这里用ok
    	// OK=true表示map有这个key,ok=false表示map没这个key
    	//如果没这个key,v等于对应类型的零值
    	v, ok := m3["wanglei"]
    	fmt.Println(v, ok) // 120 true
    
    	v1, ok := m3["name"]
    	fmt.Println(v1, ok) //0 false
    
    	_, ok = m3["mike"]
    	fmt.Println(ok) //false
    
    }
    
    //运行结果:
    120 true
    0 false
    false
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    遍历

    // map的遍历(map是无序的)
    func f21() {
    	m4 := map[string]int{
    		"wanglei": 120,
    		"小和尚":     200,
    		"shahe":   234,
    	}
    
    	//遍历键和值
    	for k, v := range m4 {
    		fmt.Println(k, v)
    	}
    
    	//只遍历键
    	for k1 := range m4 {
    		fmt.Println(k1)
    	}
    
    	//只遍历值
    	for _, v1 := range m4 {
    		fmt.Println(v1)
    	}
    }
    
    //运行结果:
    wanglei 120
    小和尚 200
    shahe 234
    wanglei
    小和尚
    shahe
    120
    200
    234
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    从map中删除键值对

    使用delete()内建函数从map中删除一组键值对,delete()函数的格式如下:

    delte(map,key)
    
    • 1

    其中,

    • map:表示要删除键值对的map
    • key:表示要删除的键值对的键
    // 从map中删除键值对
    func f22() {
    	m5 := make(map[string]int)
    	m5["猪八戒"] = 200
    	m5["孙悟空"] = 100
    	m5["唐僧"] = 150
    
    	delete(m5, "猪八戒")
    	for k, v := range m5 {
    		fmt.Printf("键为:%v 值为:%v\n", k, v)
    	}
    
    }
    
    //运行结果:
    键为:孙悟空 值为:100
    键为:唐僧 值为:150
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    map+slice 组成复杂一点的数据类型

    元素为map类型的切片
    //元素为map类型的切片
    func f23() {
    	mapSlice := make([]map[string]string, 3) //定义了一个元素为map类型的,len=cap=3的切片
    	fmt.Println(mapSlice)
    	for index, value := range mapSlice {
    		fmt.Printf("index:%d value:%v\n", index, value) // 得到的value都为map[]
    	}
    	fmt.Println("----------------after init----------------")
    	//对切片的元素进行初始化
    	mapSlice[0] = make(map[string]string)
    	mapSlice[0]["name"] = "小王子"
    	mapSlice[0]["password"] = "123456"
    	mapSlice[0]["address"] = "沙河"
    	fmt.Println(mapSlice)
    	for index, value := range mapSlice {
    		fmt.Printf("index:%d value:%v\n", index, value)
    	}
    	//继续可以按照对mapSlice[1],mapSlice[2]的元素初始化...
    }
    
    //运行结果:
    [map[] map[] map[]]
    index:0 value:map[]
    index:1 value:map[]
    index:2 value:map[]
    ----------------after init----------------
    [map[address:沙河 name:小王子 password:123456] map[] map[]]
    index:0 value:map[address:沙河 name:小王子 password:123456]
    index:1 value:map[]
    index:2 value:map[]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    值为切片类型的map
    //值为切片类型的map
    func f24() {
    	sliceMap := make(map[string][]string)
    	fmt.Println(sliceMap)
    	fmt.Println("-----------------after int-----------------")
    	key := "中国"
    	value, ok := sliceMap[key]
    	if !ok {
    		value = make([]string, 0, 2)
    	}
    	value = append(value, "北京", "上海")
    	sliceMap[key] = value //map赋值
    	fmt.Println(sliceMap)
    }
    
    //运行结果:
    map[]
    -----------------after int-----------------
    map[中国:[北京 上海]]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    练习

    1、写一个程序,统计一个字符串中每个单词出现的次数。比如:”how do you do”中how=1 do=2 you=1。

    //写一个程序,统计一个字符串中每个单词出现的次数。比如:"how do you do"中how=1 do=2 you=1
    func f25() {
    	/*
    		1、先把字符串每个单词统计出来
    		2、统计每个单词的数量
    	*/
    
    	str := "how do you do"
    	slice := strings.Split(str, " ")
    	fmt.Println(slice) //[how do you do]
    
    	//定义一个map
    	map1 := make(map[string]int)
    	for _, value := range slice {
    		_, ok := map1[value]
    		if !ok { //	如果key不存在,则给这个key的value赋值1
    			map1[value] = 1
    		} else { //如果key存在,则在之前基础上+1
    			map1[value] += 1
    		}
    	}
    	fmt.Println(map1)
    
    }
    
    //运行结果:
    [how do you do]
    map[do:2 how:1 you:1]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    2、观察下面代码,写出最终打印结果

    // 下面代码打印结果
    func f26() {
    
    	type Map map[string][]int
    	m := make(Map)
    	s := []int{1, 2}
    	s = append(s, 3)
    	fmt.Printf("%+v\n", s) // [1 2 3]
    	fmt.Printf("切片s的内存地址是:%p s: %v\n", s, s)
    
    	m["q1mi"] = s
    	fmt.Printf("m的内存地址是:%p m: %v\n", m, m)
    
    	s = append(s[:1], s[2:]...)//等价于s[1]=3
    
    	fmt.Printf("新切片s的内存地址是:%p s: %v\n", s, s) // 和之前的切片s的内存地址一样,因为底层操作的是同一个数组 [1 3]
    	fmt.Printf("%+v\n", m["q1mi"])            //map[q1mi:[1 3 3] ?
    }
    
    //运行结果
    [1 2 3]
    切片s的内存地址是:0xc0000b4000 s: [1 2 3]
    m的内存地址是:0xc000098180 m: map[q1mi:[1 2 3]]
    新切片s的内存地址是:0xc0000b4000 s: [1 3]
    [1 3 3]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
  • 相关阅读:
    一张图读懂人工智能
    没想到吧,Spring中还有一招集合注入的写法
    R语言简介|你对R语言了解多少?
    如何基于Django中的WebSockets和异步视图来实现实时通信功能
    KVM虚拟化学习总结
    [山东科技大学OJ]1370 Problem C: 编写函数:字符串的连接 之三 (Append Code)
    Netty
    Grafana + Prometheus监控篇之Windows监控Linux服务器资源
    十年技术进阶路,让我明白了三件要事(8000字长文)
    OCR-easyocr初识
  • 原文地址:https://blog.csdn.net/weixin_38753143/article/details/125544483