map基础操作

1. 字典类型(Map)

在学习任何的编程语言时,一般都会一种数据类型称为:字典(dict)或映射(map),以键值对为元素的数据集合。例如:

{
    "age":"18",
    "name":"武沛齐",
    "email":"wupeiqi@live.com"
}

这种类型最大的特点就是查找速度非常快,因为他的底层存储是基于哈希表存储的(不同语言还会有一些差异)。

取模+拉链法来快速了解下哈希表存储原理,如下图

这种结构之所以快,是因为根据key可以直接找到数据存放的位置;而其他的数据类型是需要从前到后去逐一比对,相对来说比较耗时。

以上只是基本的存储模型,而各个编程语言中的字典都会在此基础上进行相应的修改和优化(后续会深入讲解Golang中的map实现机制)。

Map的特点:

  • 键不能重复
  • 键必须可哈希(目前我们已学的数据类型中,可哈希的有:int/bool/float/string/array)
  • 无序

接下来关于map我会从两个维度来进行讲解:

  • 常见使用
  • 底层原理剖析(面试常问)

2. 声明&初始化

// userInfo := map[string]string{}
userInfo := map[string]string{"name":"武沛齐","age":"18"}

userInfo["name"]  // 武沛齐
userInfo["age"] = "20"
userInfo["email"] = "wupeiqi@live.com"
// data := make(map[int]int, 10)
data := make(map[int]int)
data[100] = 998
data[200] = 999
data := make(map[string]int)
data["100"] = 998
data["200"] = 999

// 声明,nil
var row map[string]int
row = data
data := make(map[string]int)
data["100"] = 998
data["200"] = 999

// 声明,nil
value := new(map[string]int)
// value["k1"] = 123  # 报错
value = &data

注意:键不重复 & 键必须可哈希(int/bool/float/string/array)

v1 := make(map[[2]int]float32)
v1[[2]int{1,1}] = 1.6
v1[[2]int{1,2}] = 3.4

v2 := make(map[[2]int][3]string )
v2[[2]int{1,1}] = [3]string{"武沛齐","alex","老妖"}

3. 常用操作

长度和容量

data := map[string]string{"n1":"武沛齐","n2":"alex"}
value := len(data)  // 2
// 根据参数值(10),计算出合适的容量。
// 一个map 中会包含很多桶,每个桶中可以存放8个键值对。
info := make(map[string]string, 10)

info["n1"] = "武沛齐"
info["n2"] = "alex"

v1 := len(info)  // 2
// v2 := cap(info)  // 报错

添加

data := map[string]string{"n1":"武沛齐","n2":"alex"}
data["n3"] = "eric"

修改

data := map[string]string{"n1":"武沛齐","n2":"alex"}
data["n1"] = "eric"

删除

data := map[string]string{"n1":"武沛齐","n2":"alex"}
delete(data,"n2")

查看

data := map[string]string{"n1":"武沛齐","n2":"alex"}
data["n1"]
data := map[string]string{"n1":"武沛齐","n2":"alex"}
for key,value := range data{
    fmt.Println(key,value)
}
data := map[string]string{"n1":"武沛齐","n2":"alex"}
for key := range data{
    fmt.Println(key) 
}
data := map[string]string{"n1": "武沛齐", "n2": "alex"}
for _, value := range data {
    fmt.Println(value)
}

嵌套

v1 := make(map[string]int)
v2 := make(map[string]string)
v3 := make(map[string]...)
v4 := make(map[string][2]int)
v5 := make(map[string][]int)
v6 := make(map[string]map[int]int)
v7 := make(map[string][2]map[string]string)
v7["n1"] = [2]map[string]string{ map[string]string{"name":"武沛齐","age":"18"},map[string]string{"name":"alex","age":"78"}}
v7["n2"] = [2]map[string]string{ map[string]string{"name":"eric","age":"18"},map[string]string{"name":"seven","age":"78"}}

// 伪代码
v7 = {
    n1:[
        {"name":"武沛齐","age":"18"},
        {"name":"alex","age":"78"}
    ],
    n2:[
        {"name":"eric","age":"18"},
        {"name":"seven","age":"78"}
    ]
}

前提:键不重复 & 键必须可哈希

v8 := make(map[int]int)
v9 := make(map[string]int)
v10 := make(map[float32]int)
v11 := make(map[bool]int)
v12 := make(map[ [2]int ]int)
v13 := make(map[ []int ]int) // 错误,不可哈希
v14 := make(map[ map[int]int ]int) // 错误,不可哈希
v15 := make(map[ [2][]int ]int) // 报错
v16 := make(map[ [2]map[string]string ]int) // 报错

变量赋值

v1 := map[string]string{"n1":"武沛齐","n2":"alex"}
v2 := v1

v1["n1"] = "wupeiqi"

ftm.Println(v1) // {"n1":"wupeiqi","n2":"alex"}
ftm.Println(v2) // {"n1":"wupeiqi","n2":"alex"}

特别提醒:无论是否存在扩容都指向同一个地址。

results matching ""

    No results matching ""