Golang语言之映射(map)快速入门篇

                                              作者:尹正杰

版权声明:原创作品,谢绝转载!否则将追究法律责任。

一.映射(map)定义

1.映射(map)概述

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

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

映射(map)是Go语言中内置的一种类型,它将键值相关联,我们可以通过key来获取对应的value,有点类似于其他语言的集合。

映射(map)的特点:
	- 1.map结合在使用前一定要make;
	- 2.map的key-value是无序的;
	- 3.key是不可以重复的,如果遇到重复,后一个value会替换前一个value;
	- 4.不同的key,其value是可以重复的;

2.map的语法格式

Go语言中map的定义语法如下:
	map[KeyType]ValueType
	
map类型的变量默认初始值为nil,需要使用make()函数来分配内存。语法为:
	make(map[KeyType]ValueType, [cap])
	
	相关字段说明:
    KeyType:
      表示键的类型。
    ValueType:
      表示键对应的值的类型。
    cap
      map的容量,该参数可选,但建议在初始化map的时候就为其指定一个合适的容量。
      
温馨提示:
	- 1.key,value的类型包括但不限于bool,数值型,string,指针,chan,还可以只包含前面几个类型的接口,结构体,数组等;
	- 2.key部分通常为int,string类型,value通常为数字(整数,浮点数),string,map,结构体;
	- 3.key部分不可以是slice,map,function等类型;

3.map的三种创建方式

3.1 先声明在make

package main

import "fmt"

func main() {

	// 1.声明map变量,但并没有分配堆内存空间
	var dongMan map[int]string

	// 2.必须通过make函数进行初始化,才会在堆内存中分配空间
	dongMan = make(map[int]string, 5) // map可以存放5个键值对,但实际存储超过5个依旧是可以的

	// 3.将键值对存储map中
	dongMan[20230925] = "《仙逆》"
	dongMan[20200725] = "《凡人修仙传》"
	dongMan[20201129] = "《吞噬星空》"
	dongMan[20220129] = "《永生》"
	dongMan[20140731] = "《画江湖之不良人》"
	dongMan[20131214] = "《师兄啊师兄》"
	dongMan[20021003] = "《火影忍者》"
	dongMan[20080517] = "《葫芦兄弟》"
	dongMan[19990723] = "《西游记》"

	// 4.输出集合
	fmt.Printf("dongman = %v\n", dongMan)
}

3.2 直接使用make初始化map

package main

import "fmt"

func main() {

	// 1.初始化map类型
	language := make(map[string]uint16)

	// 2.赋值
	language["C"] = 1972
	language["C++"] = 1983
	language["Python"] = 1989
	language["JAVA"] = 1995
	language["Golang"] = 2007
	language["Scala"] = 2003
	language["Ruby"] = 1993
	language["Php"] = 2004
	language["HTML"] = 1989
	language["CSS"] = 1994
	language["JavaScript"] = 1995

	// 3.查看map数据
	fmt.Printf("language = [%v]\n", language)
}

3.3 直接赋值初始化map

package main

import "fmt"

func main() {

	dbInfo := map[string]string{
		"Username": "jasonyin2020",
		"Password": "yinzhengjie",
		"DbHost":   "www.yinzhengjie.com",
		"DbPort":   "3306",
		"DbName":   "wordpress",
	}

	fmt.Printf("userInfo = %v\n", dbInfo)
}

二.map基本使用

1.map的增删改查

package main

import "fmt"

func main() {
	// 1.定义map
	constellation := make(map[string]string)

	// 2.增加
	constellation["金牛座"] = "土象星座: 0420-0520"
	constellation["处女座"] = "土象星座: 0823-0922"
	constellation["摩羯座"] = "土象星座: 1222-0119"

	// 3.修改
	constellation["狮子座"] = "火象星座: 0723-0822"

	fmt.Printf("删除前: len(constellation) = %d\n", len(constellation))

	// 4.删除指定map的key,若key不存在,并不会报错
	delete(constellation, "摩羯座")
	fmt.Printf("删除后: len(constellation) = %d\n", len(constellation))

	// 5.查找,判断某个键是否存在
	value, ok := constellation["狮子座"]
	if ok {
		fmt.Printf("狮子座的出生日期: %v\n", value)
	} else {
		fmt.Println("查无此人")
	}

	fmt.Printf("星座: %v\n", constellation)

}

2.map的遍历

package main

import "fmt"

func main() {
	constellation := make(map[string]string)

	constellation["金牛座"] = "土象星座: 0420-0520"
	constellation["处女座"] = "土象星座: 0823-0922"
	constellation["摩羯座"] = "土象星座: 1222-0119"
	constellation["狮子座"] = "火象星座: 0723-0822"

	// Go语言中使用for range遍历map,遍历map时的元素顺序与添加键值对的顺序无关。
	for key, value := range constellation {
		fmt.Printf("key = %v, value = %v\n", key, value)
	}

	fmt.Println("----- 我是分割线 -----")

	// 但我们只想遍历key的时候,仅需使用一个参数来接收哟~
	for k := range constellation {
		fmt.Printf("key = %v\n", k)
	}

}

3.嵌套map遍历

package main

import "fmt"

func main() {

	dongMan := make(map[string]map[int]string)

	// 由于map的值为map类型,因此我们需要对值先进行make再使用,否则会抛出异常
	dongMan["腾讯视频"] = make(map[int]string, 3)
	dongMan["腾讯视频"][20230925] = "《仙逆》"
	dongMan["腾讯视频"][20201129] = "《吞噬星空》"
	dongMan["腾讯视频"][20140731] = "《画江湖之不良人》"

	// 由于map的值为map类型,因此我们需要对值先进行make再使用,否则会抛出异常
	dongMan["B站"] = make(map[int]string, 2)
	dongMan["B站"][20200725] = "《凡人修仙传》"
	dongMan["B站"][20220129] = "《永生》"

	// 由于map的值为map类型,因此我们需要对值先进行make再使用,否则会抛出异常
	dongMan["优酷"] = make(map[int]string, 2)
	dongMan["优酷"][20131214] = "《师兄啊师兄》"
	dongMan["优酷"][20021003] = "《火影忍者》"

	for k1, v1 := range dongMan {
		fmt.Printf("k1 = %v\n", k1)

		for k2, v2 := range v1 {
			fmt.Printf("[%v]动漫的发行时间是: [%d]\n", v2, k2)
		}
	}
}

4.元素为map类型的切片

package main

import (
	"fmt"
)

func main() {
	// 定义一个长度为3的切片
	var mapSlice = make([]map[string]string, 3)

	// 对切片的各个元素进行遍历
	for index, value := range mapSlice {
		fmt.Printf("index: %d value: %v\n", index, value)
	}
	
	fmt.Println("----- 分割线 -----")

	// 对切片中的第一个(索引下标为0)map元素进行初始化
	mapSlice[0] = make(map[string]string, 10)
	mapSlice[0]["name"] = "Jason Yin"
	mapSlice[0]["password"] = "123456"
	mapSlice[0]["address"] = "北京市昌平区沙河镇"

	for index, value := range mapSlice {
		fmt.Printf("index: %d value: %v\n", index, value)
	}
}

5.值为切片类型的map

package main

import (
	"fmt"
)

func main() {
	// 定义一个map类型
	var sliceMap = make(map[string][]string, 3)

	key := "中国"
	value, ok := sliceMap[key]
	if !ok {
		// 如果key="中国"不存在,则对其值进行初始化为一个容量为2的字符串切片。
		value = make([]string, 0, 2)
	}

	// 紧接着,由于切片是引用类型,我们往该切片中添加2个字符串类型元素
	value = append(value, "北京", "上海")

	fmt.Printf("地址: %p, 数据: %v, 长度: %d, 容量: %d\n", value, value, len(value), cap(value))

	// 往切片追加元素,原有的切片底层数组将存不下,于是会产生新的底层数组哟~
	value = append(value, "深圳", "石家庄", "西安")
	fmt.Printf("地址: %p, 数据: %v, 长度: %d, 容量: %d\n", value, value, len(value), cap(value))

	// 注意,此处我们切片进行赋值给map的key。
	sliceMap[key] = value
	fmt.Println(sliceMap)
}

三.练习题

1.写一个程序,统计一个字符串中每个单词出现的次数

package main

import (
	"fmt"
	"strings"
)

func main() {

	// 统计一个字符串中每个单词出现的次数
	s1 := "I love you , and you ?"

	// 将字符串按照空格子串进行切割
	res := strings.Split(s1, " ")

	// 初始化用于单词统计的map
	var wordCount = make(map[string]int, 10)

	// 如果单词不存在,则将其值设置为1,若存在,则将其值进行加一操作。
	for _, value := range res {
		_, ok := wordCount[value]
		if !ok {
			wordCount[value] = 1
		} else {
			wordCount[value]++
		}
	}

	// 遍历字典
	for k, v := range wordCount {
		fmt.Printf("%s: %d\n", k, v)
	}

}

2.看代码手写结果

package main

import (
	"fmt"
)

func main() {
	// 自定义一个Map类型,底层对应的是一个map类型哟~
	type Map map[string][]int

	// 初始化咱们的自定义类型
	m := make(Map)
	s1 := []int{100, 200}
	s1 = append(s1, 300)
	fmt.Printf("s1 = %+v\n", s1)

	m["JasonYin"] = s1
	s1 = append(s1[:1], s1[2:]...)
	fmt.Printf("s1 = %+v\n", s1)
	fmt.Printf("m['JasonYn'] = %+v\n", m["JasonYin"])
}

posted @ 2024-07-26 06:23  尹正杰  阅读(43)  评论(0编辑  收藏  举报