• 8、Go语言基础之map


    1、简介

    ​映射是方便而强大的内建数据结构,它可以关联不同类型的值。其键可以是任何相等性操作符支持的类型, 如整数、浮点数、复数、字符串、指针、接口(只要其动态类型支持相等性判断)、结构以及数组。 切片不能用作映射键,因为它们的相等性还未定义。与切片一样,映射也是引用类型。 若将映射传入函数中,并更改了该映射的内容,则此修改对调用者同样可见。

    Go语言中提供的映射关系容器为map,其内部使用散列表(hash)实现。

    map是一种无序的基于key-value的数据结构,Go语言中的map是引用类型,必须初始化才能使用。

    2、map定义

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

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

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

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

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

    3、map基本使用

    map中的数据都是成对出现的,map的基本使用示例代码如下:

    package main
    
    import "fmt"
    
    func main() {
    	Info := make(map[string]int, 8)
    	Info["小李"] = 18
    	Info["小王"] = 19
    	fmt.Println(Info)
    	fmt.Println(Info["小李"])
    	fmt.Printf("type:%T
    ", Info)
        fmt.Printf("%#v", Info)
    }
    >>>
    map[小李:18 小王:19]
    18
    type:map[string]int
    map[string]int{"小李":18, "小王":19}
    

    map也支持在声明的时候填充元素,例如:

    package main
    
    import "fmt"
    
    func main() {
    	userInfo := map[string]string{
    		"user": "谢景顺",
    		"sex":  "男",
    	}
    	fmt.Println(userInfo) 
        fmt.Printf("%#v", userInfo)
    }
    
    >>>
    map[sex:男 user:谢景顺]
    map[string]string{"sex":"男", "user":"谢景顺"}
    

    4、判断某个键是否存在

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

    value, key := map[key]
    

    举个例子:

    package main
    
    import "fmt"
    
    func main() {
    	Info := make(map[string]int)
    	Info["小李"] = 18
    	Info["小王"] = 19
    	// 如果key存在status为true,v为对应的值;不存在status为false,v为值类型的零值
    	v, status := Info["小李"]
    	if status {
    		fmt.Println(v)
    	} else {
    		fmt.Println("查无此人")
    	}
    }
    
    >>>
    18
    

    5、map的遍历

    Go语言中使用for range遍历map。

    package main
    
    import "fmt"
    
    func main() {
    	Info := make(map[string]int)
    	Info["小李"] = 18
    	Info["小王"] = 19
    	Info["小张"] = 22
    	for k, v := range Info {
    		fmt.Println(k, v)
    	}
    }
    
    >>>
    小李 18
    小王 19
    小张 22
    

    只想遍历key的时候,可以按下面的写法:

    package main
    
    import "fmt"
    
    func main() {
    	Info := make(map[string]int)
    	Info["小李"] = 18
    	Info["小王"] = 19
    	Info["小张"] = 22
    	for k := range Info {
    		fmt.Println(k)
    	}
    }
    
    >>>
    小张
    小李
    小王
    

    注意: map是无序的,元素顺序与添加键值对的顺序无关。

    只想遍历value的时候,可以按下面的写法:

    package main
    
    import "fmt"
    
    func main() {
    	Info := make(map[string]int)
    	Info["小李"] = 18
    	Info["小王"] = 19
    	Info["小张"] = 22
    	for _, k := range Info {
    		fmt.Println(k)
    	}
    }
    
    >>>
    18
    19
    22
    

    6、使用delete()函数删除键值对

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

    delete(map, key)
    

    其中,

    • map:表示要删除键值对的map
    • key:表示要删除的键值对的键

    示例代码如下:

    package main
    
    import "fmt"
    
    func main() {
    	Info := make(map[string]int)
    	Info["小李"] = 18
    	Info["小王"] = 19
    	Info["小张"] = 22
    	delete(Info, "小张") //小张:22从map中删除
    	for k, v := range Info {
    		fmt.Println(k, v)
    	}
    }
    >>>
    小李 18
    小王 19
    
    

    7、按照指定顺序遍历map

    package main
    
    import (
    	"fmt"
    	"math/rand"
    	"sort"
    )
    
    func main() {
    	var storeMap = make(map[string]int, 100)
    
    	for i := 0; i < 50; i++ {
    		key := fmt.Sprintf("XX%02d", i) //生成stu开头的字符串
    		value := rand.Intn(50)          //生成0~99的随机整数
    		storeMap[key] = value
    	}
    
    	//取出map中的所有key存入切片keys
    	var keys = make([]string, 0, 100)
    	for key := range storeMap {
    		keys = append(keys, key)
    	}
    	//对切片进行排序
    	sort.Strings(keys)
    	//按照排序后的key遍历map
    	for _, key := range keys {
    		fmt.Println(key, storeMap[key])
    	}
    }
    >>>
    XX00 31
    XX01 37
    ......
    XX47 24
    XX48 9
    XX49 3
    

    8、元素为map类型的切片

    下面的代码演示了切片中的元素为map类型时的操作:

    package main
    
    import "fmt"
    
    func main() {
    	//对切片中的map元素进行初始化
    	var mapSlice = make([]map[string]string, 3)
    	for index, value := range mapSlice {
    		fmt.Printf("index:%d value:%v
    ", index, value)
    	}
    	fmt.Println("-----------------------")
    	//对切片中的map元素进行初始化
    	mapSlice[0] = make(map[string]string, 10)
    	mapSlice[0]["name"] = "小王"
    	mapSlice[0]["sex"] = "男"
    	mapSlice[0]["address"] = "北京"
    	for index, value := range mapSlice {
    		fmt.Printf("index:%d value:%v
    ", index, value)
    	}
    }
    

    9、值为切片类型的map

    下面的代码演示了map中值为切片类型的操作:

    package main
    
    import "fmt"
    
    func main() {
    	//值为切片的map
    	var sliceMap = make(map[string][]string, 3) //只完成了map的初始化
    	fmt.Println(sliceMap)
    	fmt.Println("---------------")
    	key := "中国"
    	value, status := sliceMap[key]
    	if !status {
    		value = make([]string, 0, 2)
    	}
    	value = append(value, "北京", "上海")
    	sliceMap[key] = value
    	fmt.Println(sliceMap)
    }
    >>>
    map[]
    ---------------
    map[中国:[北京 上海]]
    
    

    10、练习题

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

    方法一:

    package main
    
    import (
    	"fmt"
    	"strings"
    )
    
    func main() {
    	sentence := "how do you do"
    	words := strings.Split(sentence, " ")
    	//初始化一个map结果集,cap=3,因为句子拆分后只有3种键
    	result := make(map[string]int, 3)
    	//遍历字符串数组,让map中对应的键++
    	for _, v := range words {
    		result[v]++
    	}
    	//输出结果集
    	fmt.Println(result)
    }
    >>>
    map[do:2 how:1 you:1]
    

    方法二:

    package main
    
    import (
    	"fmt"
    	"strings"
    )
    
    func main() {
    	var s = "how do you do"
    	var wordsCount = make(map[string]int, 10)
    	words := strings.Split(s, " ")
    	for _, word := range words {
    		v, status := wordsCount[word]
    		if status {
    			wordsCount[word] = v + 1
    		} else {
    			wordsCount[word] = 1
    		}
    	}
    	for k := range wordsCount {
    		fmt.Println(k, wordsCount[k])
    	}
    
    }
    
    >>>
    how 1
    do 2
    you 1
    
    1. 观察下面代码,写出最终的打印结果。
    func main() {
    	type Map map[string][]int
    	m := make(Map)
    	s := []int{1, 2}
    	s = append(s, 3)
    	fmt.Printf("%+v
    ", s)
    	m["xxx"] = s
    	s = append(s[:1], s[2:]...)
    	fmt.Printf("%+v
    ", s)
    	fmt.Printf("%+v
    ", m["xxx"])
    }
    
    >>>
    [1 2 3]
    [1 3]
    [1 3 3]
    
  • 相关阅读:
    如何在linux系统安装redis
    关于—单例模式
    2.观察者模式(发布-订阅模式)
    1.提供者模式
    提供者模式:提供者的实例化加锁
    为已有的类添加特性,常用于数据库生成的类模型
    C#特性
    JSON.parse(jsonStr)和eval('('+jsonStr+')')
    a标签的href和onclick
    查看SQL语句执行时间/性能测试
  • 原文地址:https://www.cnblogs.com/remixnameless/p/13195313.html
Copyright © 2020-2023  润新知