## 一、定义
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为什么是非线程安全
![](https://img.kancloud.cn/24/6a/246a76b71287234454be50a1100ac88f_661x328.png)
![](https://img.kancloud.cn/ab/ba/abbad73fcbf4ea513e7695a5e22ddc83_661x396.png)
![](https://img.kancloud.cn/95/93/95937abf5db92fb6d19e9bd2265751b2_661x470.png)