Go语言学习之map

Go语言学习之map

1.map的基本介绍

map是 key-value数据结构,又称为字段或者关联数组,类似JAVA的集合

在编程中经常使用到

2.map的声明

1.语法: var map 变量名 map[keytype]valuetype

》key可以是什么类型

Golang中的map的key可以是多种类型,比如:bool,数字,String,指针,Channel.还可以包含前面几个类型的:接口,结构体,数组

通常key 为 int,string

注意:slice,map还有function不可以,因为这几个没法用==来判断

》valuetype可以是什么类型

valuetype的类型和key基本一样

通常为:数字(整数,浮点数),string,map,struct

2.map声明实例

var a map[string]string

var a map[string]int

var a map[int]string

var a map[string]map[string]string

注意:声明是不会分配内存的,初始化需要make,分配内存后才能赋值和使用

package main

import "fmt"

func main() {
	//map的声明和注意事项
	var a map[string]string
	//在使用map前,需要先make,make的作用就是给map分配数据空间
	a=make(map[string]string,10)
	a["no1"]="李白"
	a["no2"]="杜甫"
	a["no3"]="苏轼"
	a["no4"]="陆游"
	fmt.Println(a)
}

代码说明:

》map在使用前一定要make

》map的key是不能重复的,如果重复了,则以最后这个key-value为准

》map的value是可以相同的

》map的key-value是无序

》make内置函数数目

func make

func make(Type,size Integer Type)Type

内置函数make分配并初始化一个类型为切片,映射,或通道的对象,其第一个实参为类型,而非值,make的返回类型与其参数不同,而非指向它的指针,其具体结果取决于具体的类型

切片:size指定了其长度,该切片的容量等于其长度。切片支持第二个整数实参可用来指定不同的容量;它必须不小于其长度,因此make([]int,0,10)会分配一个长度为0,容量为10的切片
映射:初始化分配的创建取决于size,但产生的映射长度为0,size可以省略
这种情况下就会分配一个小的起始大小
通道:通道的缓存根据指定的缓存容量初始化,若size为零或被省略,该通道即为无缓存的

3.map的使用

方式1:

	//map的声明和注意事项
	var a map[string]string
	//在使用map前,需要先make,make的作用就是给map分配数据空间
	a=make(map[string]string,10)
	a["no1"]="李白"
	a["no2"]="杜甫"
	a["no3"]="苏轼"
	a["no4"]="陆游"
	fmt.Println(a)

方式2:


	//第二种方式
	city:=make(map[string]string)
	city["no1"]="beijing"
	city["no2"]="shanghai"
	city["no3"]="shenzhen"
	fmt.Println(city)

方式3:

//第三种方式
meinv:=map[string]string{
	"mm01":"西施"
	“mm02":"昭君"
	“mm03":"貂蝉"
}
meinv["mm03"]="玉环"

map使用的课堂案例:

演示一个key-value的value 是map的案例

比如:我们要存放3个学生信息,每个学生有name和sex信息

思路:map[string]map[string]string

代码:

package main

import "fmt"

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

	stuMap["stu01"]=make(map[string]string,3)
	stuMap["stu01"]["name"]="tom"
	stuMap["stu01"]["sex"]="男"
	stuMap["stu01"]["address"]="北京"

	stuMap["stu02"]=make(map[string]string,3)
	stuMap["stu02"]["name"]="alex"
	stuMap["stu02"]["sex"]="男"
	stuMap["stu02"]["address"]="广西"

	fmt.Println(stuMap)
	fmt.Println(stuMap["stu02"])
	fmt.Println(stuMap["stu02"]["name"])
}

4.map的增删改查操作

map增加和更新

map[“key”]=value//如果key还没有,就是增加,如果key存在就是修改

	cities:=make(map[string]string)
	cities["no1"]="北京"
	cities["no2"]="上海"
	cities["no3"]="天津"
	fmt.Println(cities)
	cities["no3"]="newYork"
	fmt.Println(cities)

map删除

说明:

delete(map,“key”),delete是一个内置函数,如果key存在,就删除该key-value,

如果Key不存在,不操作,但是也不会报错

func delete

func delete(m map[Type]Type1,key Type)

内建函数delete按照指定的键将元素从映射中删除。若m为nil或无此元素,delete不进行操作

//演示删除
delete(cities,"no1")
fmt.Println(cities)
//delete指定的key不存在时,删除不会操作,也不会报错
delete(cities,"no5")
fmt.Println(cities)

》细节说明:

如果我们要删除Map的所有key,没有一个专门的方法一次删除,可以遍历一下key,逐个删除 或者 map=make(…),make一个新的,让原来的成为垃圾,被gc回收

cities=make(map[string]string)
fmt.Println(cities)

》map查找

//ok是一个布尔值,如果有就返回true,没有就返回false
val,ok:=cities["no2"]
	if ok{
		fmt.Printf("有no2 key值为 %v \n",val)
	}else {
		fmt.Printf("没有No2 key\n")
	}

5.map的遍历

案例演示相对复杂的map遍历,该map的value 又是一个map

说明:map的遍历使用for-range结构遍历

package main

import "fmt"

func main()  {
	//使用for -range遍历map
	cities:=make(map[string]string)
	cities["no1"]="北京"
	cities["no2"]="上海"
	cities["no3"]="天津"
	for k,v:=range cities{
		fmt.Printf("k=%v v=%v \n",k,v)
	}
	//使用 for-range遍历一个结构比较复杂的map
	stuMap:=make(map[string]map[string]string)

	stuMap["stu01"]=make(map[string]string,3)
	stuMap["stu01"]["name"]="tom"
	stuMap["stu01"]["sex"]="男"
	stuMap["stu01"]["address"]="北京"

	stuMap["stu02"]=make(map[string]string,3)
	stuMap["stu02"]["name"]="alex"
	stuMap["stu02"]["sex"]="男"
	stuMap["stu02"]["address"]="广西"

	for k1,v1:=range stuMap{
		fmt.Println("k1=",k1)
		for k2,v2:=range v1{
			fmt.Printf("\t k2=%v v2=%v \n",k2,v2)
		}
		fmt.Println()
	}
}

》map的长度

func len

func len(v Type)int

内建函数len返回v的长度,这取决于具体类型:

数组: v中元素的数量
数组指针:*v 中元素的数量(v为nil时panic)
切片,映射:v中元素的数量,看v为nil,len(v)即为零
字符串:v中字节的数量
通道:通道缓存中队列(未读取)元素的数量,若v 为 nil,len(v)即为零
fmt.Println(len(stuMap))

6.map切片

1.基本介绍

切片的数据类型如果是map,则我们称为slice of map,map切片,这样使用则

map这个数就可以动态变化了

2.案例演示

要求:使用一个map来记录美女的信息,name和age,

也就是说一个美女对应一个map,并且美女的个数可以动态增加


package main

import "fmt"

func main() {
	var mm []map[string]string

	mm=make([]map[string]string,2)//准备放入两个美女
	//增加第一个mm的信息
	if mm[0]==nil{
		mm[0]=make(map[string]string,2)
		mm[0]["name"]="韩雪"
		mm[0]["age"]="28"
	}

	if mm[1]==nil{
		mm[1]=make(map[string]string,2)
		mm[1]["name"]="章子怡"
		mm[1]["age"]="38"
	}
	//这种写法会导致越界
	//if mm[2]==nil{
	//	mm[2]=make(map[string]string,2)
	//	mm[2]["name"]="章子怡"
	//	mm[2]["age"]="38"
	//}
	//这里我们需要使用到切片的append函数,可以动态增加mm
	//先定义个mm的信息
	mm2:=map[string]string{
		"name":"柳如是",
		"age":"468",
	}
	mm=append(mm,mm2)
	fmt.Println(mm)
}

7.map排序

1.基本介绍

1》golang中没有一个专门的方法针对map的key进行排序

2》golang中得map默认是无序的,注意也不是按照添加的顺序存放的,你每次遍历,得到的输出可能不一样

3》golang中的Map的排序,是先将Key进行排序,然后根据Key值遍历输出即可

2,案例演示

package main

import (
	"fmt"
	"sort"
)

func main() {
	//map的排序
	map1:=make(map[int]int,10)

	map1[10]=100
	map1[1]=8
	map1[6]=7
	map1[3]=5

	fmt.Println(map1)
	//如果按照map的key的排序进行输出
	//1.现将Map的key放入到切片中
	//2.对切片排序
	//3.遍历切片,然后按照key来输出Map的值
	var keys[]int
	for k,_:=range map1{
		keys=append(keys,k)
	}
	//排序
	sort.Ints(keys)
	fmt.Println(keys)
	//
	for _,k:=range keys{
		fmt.Printf("map1[%v]=%v \n",k,map1[k])
	}
}

8.map的使用细节

1》map是引用类型,遵守引用类型传递的机制,在一个函数接收map,修改后,会直接修改原来的map

package main

import "fmt"

func modify(map1 map[int]int)  {
	map1[10]=1000
}
func main() {
	
	map1:=make(map[int]int)
	map1[1]=10
	map1[2]=20
	map1[10]=999
	modify(map1)
	//map1[10]=1000,说明Map遵循引用类型的传递机制
	fmt.Println(map1)
}

2)map的容量到达后,再想map增加元素,会自动扩容,并不会发生panic,也就是说 map的容量是动态增长的

3)map的value也经常使用struct类型,更适合管理复杂的数据(比前面value是一个map更好),比如:value为 Studetnt结构体

结构体:初体验

9.map的练习

1》使用map[string]map[string]string 的map类型

2》key:表示用户名,是唯一的,不可以重复

3》如果某个用户名存在,就将其密码修改“666666”,如果不存在就增加这个用户信息,包括昵称(name,密码pwd)

4》编写一个函数modifyUser(users map[string]map[string]string,name string)

package main

import "fmt"

func modifyUsers(users map[string]map[string]string,name string){
	//判断users中是否有name
	if users[name]!=nil{
		//有这个用户
		users[name]["pwd"]="8888"
	}else {
		//没有这个用户
		users[name]= make(map[string]string,2)
		users[name]["pwd"]="8888"
		users[name]["name"]="昵称"+name
	}
}
func main() {

	users:=make(map[string]map[string]string,10)
	users["zhangsan"]=make(map[string]string,3)
	users["zhangsan"]["pwd"]="12345"
	users["zhangsan"]["name"]="擎天柱"

	modifyUsers(users,"tome")
	modifyUsers(users,"zhangsan")
	modifyUsers(users,"lily")

	fmt.Println(users)
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值