三天Golang快速入门—Map哈希表

Map哈希表

Map介绍

无介绍,就是K-V结构的字典。

Map的声明定义

package main

import "fmt"

func main() {
	/*
		map声明语法
		var 变量名 map[keytype]valuetype

		var m1 map[string]string
		var m2 map[int]string
		var m3 map[int]map[string]string // map的value又是value

		map声明不会分配内存,必须make初始化才可以使用
	*/
	// 声明map方式一
	//make函数可以合理申请一大块内存,避免后续扩张时性能问题
	var m1 map[string]string
	//标注map的初始容量为10
	m1 = make(map[string]string, 10)
	m1["一号"] = "大狗子"
	m1["二号"] = "二狗子"
	fmt.Println(m1)

	//声明方式二
	m2 := make(map[string]string)
	m2["男"] = "小黑"
	m2["女"] = "小红"
	fmt.Println(m2)

	//声明方式三
	m3 := map[string]string{
		"坦克": "萝莉",
		"细狗": "京巴",
		"舔狗": "王二",
	}
	m3["战狼"] = "吴京"
	fmt.Println(m3)
}

Map增删改查

package main

import "fmt"

func main() {
	m1 := map[string]string{
		"k1": "v1",
		"k2": "v2",
	}

	//插入值
	m1["k3"] = "v3"
	fmt.Printf("插入后m1的值:%v\n", m1)

	//修改值
	m1["k1"] = "v111"
	fmt.Printf("修改k1后:%v\n", m1)

	//查找值
	val, ok := m1["k4"]
	if ok {
		fmt.Printf("k4: %v\n", val)
	}

	//长度:键值对数量
	m1Len := len(m1)
	fmt.Printf("m1长度:%v\n", m1Len)

	//判断key是否存在
	if val, ok := m1["k4"]; !ok {
		fmt.Printf("此key不存在\n")
	} else {
		fmt.Printf("此key的值:%v\n", val)
	}

	//删除map的key,如果key不存在,delete不进行操作
	//一次性删除所有key可以遍历下,逐个删除
	//也可以重新make新map,让原本map被gc回收
	if _, ok := m1["k3"]; ok {
		delete(m1, "k3")
		fmt.Printf("已删除m1中的k3\n")
	} else {
		fmt.Printf("无法删除,此key不存在")
	}
	fmt.Printf("此时m1为:%v\n", m1)
}

Map遍历

1.使用for-range遍历

package main

import "fmt"

func main() {
	//循环生产10个key的map
	m1 := make(map[int]int)
	for i := 0; i < 10; i++ {
		m1[i] = i + 1
		fmt.Printf("m1的key:%v value:%v\n", i, m1[i])
	}
	fmt.Println(m1)
	fmt.Println("---分割线---")
	//循环遍历map的值
	for k, v := range m1 {
		fmt.Printf("m1的key:%v m1的值%v\n", k, v)
	}
}

2.遍历嵌套map

package main

import "fmt"

func main() {
	//make初始化第一层map 分配内存
	stuMap := make(map[string]map[string]string)
	//第二次map初始化
	stuMap["stu01"] = make(map[string]string)
	stuMap["stu01"]["名字"] = "王二狗"
	stuMap["stu01"]["年龄"] = "20"

	//map必须make后才能使用
	stuMap["stu02"] = make(map[string]string)
	stuMap["stu02"]["名字"] = "傻鸟"
	stuMap["stu02"]["年龄"] = "21"

	fmt.Println(stuMap)

	//取出所有学生的信息
	for k, v := range stuMap {
		fmt.Printf("k值是学生:%v v值是学生信息:%v\n", k, v)
		for k1, v1 := range v {
			fmt.Printf("\tk1:%v v1:%v\n", k1, v1)
		}
	}
}

Map切片

//声明一个切片且类型是Map,称作Slice of Map
package main

import "fmt"

func main() {
	//声明map切片
	//默认值 [map[] map[] map[] map[] map[]]
	sliceMap := make([]map[string]string, 5)
	for i := 0; i < 5; i++ {
		//map必须初始化再用,遍历初始化
		sliceMap[i] = make(map[string]string)
	}
	sliceMap[0]["名字"] = "二狗子"
	sliceMap[1]["性别"] = "未知"
	sliceMap[2]["体重"] = "三百斤"
	fmt.Println(sliceMap)
	fmt.Printf("容量:%v,长度:%v\n", cap(sliceMap), len(sliceMap))

	//动态扩容map切片,用append函数
	newScliceMap := map[string]string{
		"姓名": "鸡蛋",
		"爱好": "大炮",
	}
	//append函数进行切片扩容 动态增加
	sliceMap = append(sliceMap, newScliceMap)
	fmt.Println(sliceMap)
	fmt.Printf("容量:%v,长度:%v\n", cap(sliceMap), len(sliceMap))
}

Map排序

map默认是无序的,每次遍历都是不同的结果。
Go没有针对MAp的key排序方法。
必须先对Key排序,然后根据Key拿value。

package main

import (
	"fmt"
	"sort"
)

func main() {
	//定义一个map变量
	m := map[string]string{"q": "q", "w": "w", "e": "e", "r": "r", "t": "t", "y": "y"}
	fmt.Println(m)
	//定义一个string类型切片
	var slice []string
	//循环变量map 取出所有的key和value
	for k, _ := range m {
		//循环将key添加到切片中
		slice = append(slice, k)
	}
	fmt.Printf("切片slice值:%v\n", slice)
	//调用排序包,对切片进行排序,按照字母顺序排序
	sort.Strings(slice[:])
	fmt.Printf("排序后:%v\n", slice)
	for _, v := range slice {
		fmt.Printf("排序后 m[%v]=%v\n", v, m[v])
	}
}

Map使用细节

1.map是引用类型,遵循引用类型传递的机制,在函数接收map参数,对map修改是直接操作原本的map
2.map可以自动扩容,动态增长

package main

import "fmt"

func main() {
	// 初始化m1 限制容量3
	m1 := make(map[int]int, 3)

	for i := 0; i < 10; i++ {
		m1[i] = i + i
	}
	fmt.Println(m1)
	fmt.Printf("m1元素个数:%v", len(m1))
}

3.map的value也可以是struct类型,适合更复杂的数据

package main

import "fmt"

type Stu struct {
	Name    string
	Age     int
	Address string
}

func main() {
	//map的key是学号
	//map的value是结构体{姓名、年龄、住址}
	students := make(map[int]Stu, 10)
	//初始化结构体,不需要写key,顺序value即可
	stu1 := Stu{"张三", 20, "北京"}
	stu2 := Stu{"李四", 40, "上海"}
	students[1001] = stu1
	students[1002] = stu2
	fmt.Println(students)
	//遍历 取出学生信息
	for k, v := range students {
		fmt.Printf("学生编号%v\n", k)
		fmt.Printf("学生姓名%v\n", v.Name)
		fmt.Printf("学生年纪%v\n", v.Age)
		fmt.Printf("学生住址%v\n", v.Address)
		fmt.Println("--------")
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不想敲代码的运维

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值