## 一、定義
Map 是一種無序的鍵值對的集合。Map 最重要的一點是通過 key 來快速檢索數據,key 類似于索引,指向數據的值。
Map 是一種集合,所以我們可以像迭代數組和切片那樣迭代它。不過,Map 是無序的,我們無法決定它的返回順序,這是因為 Map 是使用 hash 表來實現的。
#### 格式
~~~
/* 聲明變量,默認 map 是 nil */
var map_variable map[key_data_type]value_data_type
/* 使用 make 函數 */
map_variable := make(map[key_data_type]value_data_type)
~~~
#### 2、實例
~~~
package main
import "fmt"
func main() {
countryCapitalMap := make(map[string]string)
/* map插入key - value對,各個國家對應的首都 */
countryCapitalMap["France"] = "巴黎"
countryCapitalMap["Italy"] = "羅馬"
countryCapitalMap["Japan"] = "東京"
countryCapitalMap["India "] = "新德里"
/*使用鍵輸出地圖值 */
for country := range countryCapitalMap {
fmt.Println(country, "首都是", countryCapitalMap[country])
}
/*查看元素在集合中是否存在 */
capital, ok := countryCapitalMap["American"] /*如果確定是真實的,則存在,否則不存在 */
/*fmt.Println(capital) */
/*fmt.Println(ok) */
if ok {
fmt.Println("American 的首都是", capital)
} else {
fmt.Println("American 的首都不存在")
}
}
~~~
執行結果:
Italy 首都是 羅馬
Japan 首都是 東京
India 首都是 新德里
France 首都是 巴黎
American 的首都不存在
#### 3、map的特點
(1)map集合在使用前一定要make
(2)map的key-value是無序的
(3)key是不可以重復的,如果遇到重復,后一個value會替換前一個value
(4)value可以重復的
#### 4、map的定義
```
package?main
import?"fmt"
func?main(){
????????//方式1:
????????//定義map變量:
????????var?a?map\[int\]string
????????//只聲明map內存是沒有分配空間
????????//必須通過make函數進行初始化,才會分配空間:
????????a?=?make(map\[int\]string,10)?//map可以存放10個鍵值對
????????//將鍵值對存入map中:
????????a\[20095452\]?=?"張三"
????????a\[20095387\]?=?"李四"
????????//輸出集合
????????fmt.Println(a)
????????//方式2:
????????b?:=?make(map\[int\]string)
????????b\[20095452\]?=?"張三"
????????b\[20095387\]?=?"李四"
????????fmt.Println(b)
????????//方式3:
????????c?:=?map\[int\]string{
????????????????20095452?:?"張三",
????????????????20098765?:?"李四",
????????}
????????c\[20095387\]?=?"王五"
????????fmt.Println(c)
}
```
## 二、delete() 函數
#### 1、map的清空與刪除
(1)如果我們要刪除map的所有key?,沒有一個專門的方法一次刪除,可以遍歷一下key,逐個刪除
(2)或者map?=?make(...),make一個新的,讓原來的成為垃圾,被gc回收
delete() 函數用于刪除集合的元素, 參數為 map 和其對應的 key。實例如下:
#### 實例
~~~
package main
import "fmt"
func main() {
countryCapitalMap := make(map[string]string)
/* map插入key - value對,各個國家對應的首都 */
countryCapitalMap["France"] = "巴黎"
countryCapitalMap["Italy"] = "羅馬"
countryCapitalMap["Japan"] = "東京"
countryCapitalMap["India "] = "新德里"
for country := range countryCapitalMap {
fmt.Println(country, "刪除前=》首都是", countryCapitalMap[country])
}
fmt.Println("++++++++++++++++++++++++")
delete(countryCapitalMap, "France")
for country := range countryCapitalMap {
fmt.Println(country, "刪除后=》首都是", countryCapitalMap[country])
}
}
~~~
執行結果:
Italy 刪除前=》首都是 羅馬
Japan 刪除前=》首都是 東京
India 刪除前=》首都是 新德里
France 刪除前=》首都是 巴黎
++++++++++++++++++++++++
Italy 刪除后=》首都是 羅馬
Japan 刪除后=》首都是 東京
India 刪除后=》首都是 新德里
## 三、 map遍歷的結果每次都不同的原因
* map在遍歷的時候,并不是從固定的0號bucket開始遍歷的,每次遍歷,都會從一個隨機值序號的bucket,再從其中隨機的cell開始遍歷
* map遍歷的時候,是按需遍歷bucket,同時按需遍歷bucket和其overflow?bucket?中的cell。但是map在擴容后,會發生key的搬遷,這造成原來落在一個bucket中的key,搬遷后,有可能會落到其他bucket中了,從這個角度看,遍歷map的結果就不可能按照原來的順序了。
## 四、map為什么是非線程安全


