map

Go语言中提供的映射关系容器为map,其内部使用散列表(hash)实现。

map是一种无序的基于key-value的数据结构,Go语言中的map是引用类型,必须初始化才能使用。

定义

1
2
3
map[keyType]valusType
//keyType:map的key类型
//valusType:map的值类型

map类型的变量默认初始值为nil,需要使用make()来分配内存。

1
2
//定义并初始化一个map
a := make(map[keyType]valusType, [cap])

//cap为可选参数,但我们应该在初始化map是就为其指定一个合适的容量。

map的基本使用

1
2
3
4
5
6
//声明时并初始化map的值
b := map[string]string{
"username": "小亮",
"password": "123456",
}
fmt.Println(b) // map[password:123456 username:小亮]
1
2
3
4
5
6
7
8
9
10
//定义并初始化一个map
a := make(map[int]string, 3)
//向map中存放数据
a[1] = "张三"
a[2] = "李四"
a[3] = "王二"

//从map中获取数据
fmt.Println(a[1]) // "张三"
fmt.Println(a[4]) // "" 访问map中不存在的值是返回其valueType的零值

判断某个键是否存在

1
value, flag := map[key]
1
2
3
4
5
6
7
8
9
//判断某个见是否存在
c := make(map[string]string, 3)
c["a"] = "你好"
c["b"] = "No"

value, ok := c["a"]
fmt.Printf("value:%v flag:%v\n", value, ok) //value:你好 flag:true
value, ok = c["c"]
fmt.Printf("value:%v flag:%v\n", value, ok) //value: flag:false

map的遍历

for-range遍历map

1
2
3
4
5
6
7
8
9
d := map[string]string{
"a":"张三",
"b":"李四",
"c":"王二",
}

for key,value := range d{
fmt.Printf("%s : %s\n", key, value)
}

只需要遍历key时

1
2
3
for key := range d{
fmt.Println(key)
}

delete()删除键值对

1
delete(map, key)

按照指定顺序遍历

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
func sortmap() {
rand.Seed(time.Now().UnixNano()) //初始化随机数种子

var scoreMap = make(map[string]int, 200)
for i := 0; i < 100; i++ {
key := fmt.Sprintf("student%02d", i); //生成stu开头的字符串
value := rand.Intn(100) //生成0~99的随机数
scoreMap[key] = value
}

//把map的key取出存放到切片中
keyslice := make([]string, 0, 100)
for key := range scoreMap{
keyslice = append(keyslice, key)
}

//对切片进行排序
sort.Strings(keyslice)
for _, name := range keyslice{
fmt.Printf("%s : %d\n", name, scoreMap[name])
}
}

元素为map的切片

1
2
3
4
5
6
7
//map类型的切片
mapslice := make([]map[string]string, 3)
//先对切片中的map进行初始化,才能往切片里的map存放数据,不然无法对nil 的map填充数据
mapslice[0] = make(map[string]string)
mapslice[0]["a"] = "张三"
fmt.Println(mapslice) //[map[a:张三] map[] map[]]

元素为切片的map

1
2
3
4
//切片类型的map
slicemap := make(map[string][]int, 3)
slicemap["a"] = []int{1, 2, 3, 4}
fmt.Println(slicemap) //map[a:[1 2 3 4]]

练习

1、写一个程序,统计一个字符串中每个单词出现的次数。比如:”how do you do”中how=1 do=2 you=1。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
func homework() {
str := "how do you do"
split := strings.Split(str, " ") // 根据空格分隔字符串为切片
countMap := make(map[string]int, 5) // 使用map统计单词出现数量,key:单词 value: 数量
for _, value := range split { // 遍历所有单词
v, ok := countMap[value] //判断map是否存在该单词
if ok {
countMap[value] = v + 1 //存在则数量加一
} else {
countMap[value] = 1 // 不存在则放入map,设置数量为1
}
}
fmt.Println(countMap)
}

2、观察下面代码,写出最终的打印结果。

1
2
3
4
5
6
7
8
9
10
11
func main() {
type Map map[string][]int
m := make(Map)
s := []int{1, 2}
s = append(s, 3)
fmt.Printf("%+v\n", s)
m["q1mi"] = s
s = append(s[:1], s[2:]...)
fmt.Printf("%+v\n", s)
fmt.Printf("%+v\n", m["q1mi"])
}