作者:尹正傑
版權宣告:原創作品,謝絕轉載!否則將追究法律責任。
目錄
- 一.對映(map)定義
- 1.對映(map)概述
- 2.map的語法格式
- 3.map的三種建立方式
- 3.1 先宣告在make
- 3.2 直接使用make初始化map
- 3.3 直接賦值初始化map
- 二.map基本使用
- 1.map的增刪改查
- 2.map的遍歷
- 3.巢狀map遍歷
- 4.元素為map型別的切片
- 5.值為切片型別的map
- 三.練習題
- 1.寫一個程式,統計一個字串中每個單詞出現的次數
- 2.看程式碼手寫結果
一.對映(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"])
}