九、map
9.1 map概述
-
map是key-value數(shù)據(jù)結(jié)構(gòu),又稱(chēng)為字段或者關(guān)聯(lián)數(shù)組。類(lèi)似其它編程語(yǔ)言的集合,在編程中是經(jīng)常使用到
-
基本語(yǔ)法
var map 變量名 map[keytype]valuetype
-
key可以是什么類(lèi)型
golang中的map,的 key 可以是很多種類(lèi)型,比如 bool, 數(shù)字,string, 指針,channel, 還可以是只包含前面幾個(gè)類(lèi)型的 接口, 結(jié)構(gòu)體, 數(shù)組
通常 key 為 int 、 string
注意:slice, map 還有 function 不可以,因?yàn)檫@幾個(gè)沒(méi)法用 ==來(lái)判斷
- value可以是什么類(lèi)型
valuetype的類(lèi)型和key基本一樣,不再贅述了
通常為: 數(shù)字(整數(shù),浮點(diǎn)數(shù)),string,map,struct
9.2 map聲明
-
map聲明的舉例:
var a map[string]string var a map[string]int var a map[int]string var a map[string]map[string]string
注意:聲明是不會(huì)分配內(nèi)存的,初始化需要make ,分配內(nèi)存后才能賦值和使用。
案例演示:
package main
import (
"fmt"
)
func main() {
//map的聲明和注意事項(xiàng)
var a map[string]string
//在使用map前,需要先make , make的作用就是給map分配數(shù)據(jù)空間
a = make(map[string]string, 10)
a["no1"] = "宋江" //ok?
a["no2"] = "吳用" //ok?
a["no1"] = "武松" //ok?
a["no3"] = "吳用" //ok?
fmt.Println(a)
}
- 對(duì)上面代碼的說(shuō)明
1 ) map在使用前一定要make
2 ) map的key是不能重復(fù),如果重復(fù)了,則以最后這個(gè)key-value為準(zhǔn)
3 ) map的value是可以相同的.
4 ) map的 key-value是無(wú)序
5 ) make內(nèi)置函數(shù)數(shù)目
9.3 map的使用
方式 1
package main
import (
"fmt"
)
func main() {
//第一種使用方式
var a map[string]string
//在使用map前,需要先make , make的作用就是給map分配數(shù)據(jù)空間
a = make(map[string]string, 10)
a["no1"] = "宋江" //ok?
a["no2"] = "吳用" //ok?
a["no1"] = "武松" //ok?
a["no3"] = "吳用" //ok?
fmt.Println(a)
}
方式 2
package main
import (
"fmt"
)
func main() {
//第二種方式
cities := make(map[string]string)
cities["no1"] = "北京"
cities["no2"] = "天津"
cities["no3"] = "上海"
fmt.Println(cities)
}
方式 3
package main
import (
"fmt"
)
func main() {
//第三種方式
heroes := map[string]string{
"hero1" : "宋江",
"hero2" : "盧俊義",
"hero3" : "吳用",
}
heroes["hero4"] = "林沖"
fmt.Println("heroes=", heroes)
}
9.4 map操作
- map增改
map[“key”]=value//如果 key 還沒(méi)有,就是增加,如果 key 存在就是修改。
- map刪除:
說(shuō)明:delete(map,“key”) ,delete是一個(gè)內(nèi)置函數(shù),如果key存在,就刪除該key-value,如果key不存在,不操作,但是也不會(huì)報(bào)錯(cuò)
package main
import (
"fmt"
)
func main() {
//第二種方式
cities := make(map[string]string)
cities["no1"] = "北京"
cities["no2"] = "天津"
cities["no3"] = "上海"
fmt.Println(cities) // map[no1:北京 no2:天津 no3:上海]
//演示刪除
delete(cities, "no1")
fmt.Println(cities) // map[no2:天津 no3:上海]
//當(dāng)delete指定的key不存在時(shí),刪除不會(huì)操作,也不會(huì)報(bào)錯(cuò)
delete(cities, "no4")
fmt.Println(cities) // map[no2:天津 no3:上海]
}
細(xì)節(jié)
如果我們要?jiǎng)h除map的所有key,沒(méi)有一個(gè)專(zhuān)門(mén)的方法一次刪除,可以遍歷一下key,逐個(gè)刪除或者 map=make(…),make一個(gè)新的,讓原來(lái)的成為垃圾,被gc回收
package main
import (
"fmt"
)
func main() {
//第二種方式
cities := make(map[string]string)
cities["no1"] = "北京"
cities["no2"] = "天津"
cities["no3"] = "上海"
fmt.Println(cities)
//如果希望一次性刪除所有的key
//1. 遍歷所有的key,如何逐一刪除 [遍歷]
//2. 直接make一個(gè)新的空間
cities = make(map[string]string)
fmt.Println(cities)
}
- map 查找
package main
import (
"fmt"
)
func main() {
//第二種方式
cities := make(map[string]string)
cities["no1"] = "北京"
cities["no2"] = "天津"
cities["no3"] = "上海"
fmt.Println(cities)
//演示map的查找
val, ok := cities["no2"]
if ok {
fmt.Printf("有no1 key 值為%v\n", val)
} else {
fmt.Printf("沒(méi)有no1 key\n")
}
}
- map遍歷
map的遍歷使用 for-range 的結(jié)構(gòu)遍歷
復(fù)雜案例
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)
}
fmt.Println("cities 有", len(cities), " 對(duì) key-value")
//使用for-range遍歷一個(gè)結(jié)構(gòu)比較復(fù)雜的map
studentmap := make(map[string]map[string]string)
studentmap["stu01"] = make(map[string]string, 3)
studentmap["stu01"]["name"] = "tom"
studentmap["stu01"]["sex"] = "男"
studentmap["stu01"]["address"] = "北京長(zhǎng)安街~"
studentmap["stu02"] = make(map[string]string, 3) //這句話不能少!!
studentmap["stu02"]["name"] = "mary"
studentmap["stu02"]["sex"] = "女"
studentmap["stu02"]["address"] = "上海黃浦江~"
for k1, v1 := range studentmap {
fmt.Println("k1=", k1)
for k2, v2 := range v1 {
fmt.Printf("\t k2=%v v2=%v\n", k2, v2)
}
fmt.Println()
}
}
map的長(zhǎng)度:len()
9.5 map切片
切片的數(shù)據(jù)類(lèi)型如果是 map ,則我們稱(chēng)為 sliceofmap, map 切片,這樣使用則 map 個(gè)數(shù)就可以動(dòng)態(tài)變化了。
-
案例演示
要求:使用一個(gè)map來(lái)記錄monster的信息 name 和 age, 也就是說(shuō)一個(gè)monster對(duì)應(yīng)一個(gè)map,并且妖怪的個(gè)數(shù)可以動(dòng)態(tài)的增加=> map 切片
package main
import (
"fmt"
)
func main() {
//演示map切片的使用
/*
要求:使用一個(gè)map來(lái)記錄monster的信息 name 和 age, 也就是說(shuō)一個(gè)
monster對(duì)應(yīng)一個(gè)map,并且妖怪的個(gè)數(shù)可以動(dòng)態(tài)的增加=>map切片
*/
//1. 聲明一個(gè)map切片
var monsters []map[string]string
monsters = make([]map[string]string, 2) //準(zhǔn)備放入兩個(gè)妖怪
//2. 增加第一個(gè)妖怪的信息
if monsters[0] == nil {
monsters[0] = make(map[string]string, 2)
monsters[0]["name"] = "牛魔王"
monsters[0]["age"] = "500"
}
if monsters[1] == nil {
monsters[1] = make(map[string]string, 2)
monsters[1]["name"] = "玉兔精"
monsters[1]["age"] = "400"
}
// 下面這個(gè)寫(xiě)法越界。
// if monsters[2] == nil {
// monsters[2] = make(map[string]string, 2)
// monsters[2]["name"] = "狐貍精"
// monsters[2]["age"] = "300"
// }
//這里我們需要使用到切片的append函數(shù),可以動(dòng)態(tài)的增加monster
//1. 先定義個(gè)monster信息
newMonster := map[string]string{
"name" : "新的妖怪~火云邪神",
"age" : "200",
}
monsters = append(monsters, newMonster)
fmt.Println(monsters)
}
9.6 map排序
1 ) golang中沒(méi)有一個(gè)專(zhuān)門(mén)的方法針對(duì)map的key進(jìn)行排序
2 ) golang中的map默認(rèn)是無(wú)序的,注意也不是按照添加的順序存放的,你每次遍歷,得到的輸出可能不一樣.
3 ) golang中map的排序,是先將key進(jìn)行排序,然后根據(jù)key值遍歷輸出即可
package main
import (
"fmt"
"sort"
)
func main() {
//map的排序
map1 := make(map[int]int, 10)
map1[10] = 100
map1[1] = 13
map1[4] = 56
map1[8] = 90
fmt.Println(map1)
//如果按照map的key的順序進(jìn)行排序輸出
//1. 先將map的key 放入到 切片中
//2. 對(duì)切片排序
//3. 遍歷切片,然后按照key來(lái)輸出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])
}
}
9.7 map使用細(xì)節(jié)
1 ) map是引用類(lèi)型,遵守引用類(lèi)型傳遞的機(jī)制,在一個(gè)函數(shù)接收map,修改后,會(huì)直接修改原來(lái)的map
package main
import (
"fmt"
)
func modify(map1 map[int]int) {
map1[10] = 900
}
func main() {
//map是引用類(lèi)型,遵守引用類(lèi)型傳遞的機(jī)制,在一個(gè)函數(shù)接收map,
//修改后,會(huì)直接修改原來(lái)的map
map1 := make(map[int]int, 2)
map1[1] = 90
map1[2] = 88
map1[10] = 1
map1[20] = 2
modify(map1)
// 看看結(jié)果, map1[10] = 900 ,說(shuō)明map是引用類(lèi)型
fmt.Println(map1)
}
2 ) map的容量達(dá)到后,再想map增加元素,會(huì)自動(dòng)擴(kuò)容,并不會(huì)發(fā)生panic,也就是說(shuō)map 能動(dòng)態(tài)的增長(zhǎng) 鍵值對(duì)(key-value)文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-400165.html
3 ) map的 value 也經(jīng)常使用 struct 類(lèi)型,更適合管理復(fù)雜的數(shù)據(jù)(比前面value是一個(gè)map更好),比如value為 Student結(jié)構(gòu)體文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-400165.html
package main
import (
"fmt"
)
func modify(map1 map[int]int) {
map1[10] = 900
}
//定義一個(gè)學(xué)生結(jié)構(gòu)體
type Stu struct {
Name string
Age int
Address string
}
func main() {
//map的value 也經(jīng)常使用struct 類(lèi)型,
//更適合管理復(fù)雜的數(shù)據(jù)(比前面value是一個(gè)map更好),
//比如value為 Student結(jié)構(gòu)體
//1.map 的 key 為 學(xué)生的學(xué)號(hào),是唯一的
//2.map 的 value為結(jié)構(gòu)體,包含學(xué)生的 名字,年齡, 地址
students := make(map[string]Stu, 10)
//創(chuàng)建2個(gè)學(xué)生
stu1 := Stu{"tom", 18, "北京"}
stu2 := Stu{"mary", 28, "上海"}
students["no1"] = stu1
students["no2"] = stu2
fmt.Println(students)
//遍歷各個(gè)學(xué)生信息
for k, v := range students {
fmt.Printf("學(xué)生的編號(hào)是%v \n", k)
fmt.Printf("學(xué)生的名字是%v \n", v.Name)
fmt.Printf("學(xué)生的年齡是%v \n", v.Age)
fmt.Printf("學(xué)生的地址是%v \n", v.Address)
fmt.Println()
}
}
到了這里,關(guān)于Go語(yǔ)言精修(尚硅谷筆記)第九章的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!