feat(map): 添加map基础概念和使用示例 - 新增map数据结构的基础概念介绍 - 添加切片与map对比的示例代码和说明 - 实现person查找的slice vs map性能对比示例 - 添加map声明、初始化、访问、删除、遍历等完整操作示例 - 补充map作为引用类型的说明和示意图 - 新增使用map进行去重的功能说明 - 添加slices_vs_map.drawio图表文件 - 更新练习题目,增加去重相关的练习 该提交完整介绍了Go语言中map的核心概念和实际应用, 帮助理解map相比切片在查找效率上的优势。 ```
136 lines
3.2 KiB
Go
136 lines
3.2 KiB
Go
package main
|
||
|
||
import "fmt"
|
||
|
||
var (
|
||
globalMap = map[string]string{}
|
||
)
|
||
|
||
func main() {
|
||
personList := []Person{}
|
||
personList = append(personList, Person{
|
||
Name: "张三",
|
||
Age: 18,
|
||
})
|
||
personList = append(personList, Person{
|
||
Name: "李四",
|
||
Age: 20,
|
||
})
|
||
|
||
// 如何找到李四这个对象
|
||
for _, person := range personList {
|
||
if person.Name == "李四" {
|
||
// 找到了
|
||
fmt.Println("找到李四:", person)
|
||
break
|
||
}
|
||
}
|
||
|
||
// 如果我这个切切片非常大, 上百万, 上千万
|
||
// 通过切片查找一个元素, 效率非常低, O(n)
|
||
// 这时可以使用 map 来优化查找效率
|
||
|
||
// 使用map 来存储人员信息, key 是姓名, value 是 Person 对象
|
||
personMap := map[string]Person{}
|
||
personMap["张三"] = Person{
|
||
Name: "张三",
|
||
Age: 22,
|
||
}
|
||
personMap["李四"] = Person{
|
||
Name: "李四",
|
||
Age: 24,
|
||
}
|
||
fmt.Println("通过Map直接找到李四: ", personMap["李四"])
|
||
|
||
/*
|
||
1. 声明和初始化
|
||
map[keyType]valueType
|
||
keyType 必须是可以hash的类型, 常见的可以是 string, int, float64, bool
|
||
*/
|
||
// 先声明,在初始化
|
||
var animalMap map[string]string
|
||
// animalMap = make(map[string]string)
|
||
// 初始化一个空的 map
|
||
animalMap = map[string]string{}
|
||
fmt.Println("animalMap:", animalMap)
|
||
|
||
// 声明的同时初始化(常用, 简短声明用不了的情况, 只能用 var 声明)
|
||
var cityMap = map[string]string{
|
||
"北京": "北京是中国的首都",
|
||
"上海": "上海是中国的经济中心",
|
||
"广州": "广州是中国的南大门",
|
||
}
|
||
fmt.Println("cityMap:", cityMap)
|
||
|
||
// 简短声明(最常用, 推荐)
|
||
cityMap1 := map[string]string{
|
||
"北京": "北京是中国的首都",
|
||
"上海": "上海是中国的经济中心",
|
||
"广州": "广州是中国的南大门",
|
||
}
|
||
fmt.Println("cityMap:", cityMap1)
|
||
|
||
/* * 2. 访问元素
|
||
value := map[key]
|
||
*/
|
||
fmt.Println("== 访问元素 ==")
|
||
beijingDesc := cityMap1["北京"]
|
||
fmt.Println("北京的描述是:", beijingDesc)
|
||
|
||
/* * 3. 删除元素
|
||
delete(map, key)
|
||
*/
|
||
delete(cityMap1, "广州")
|
||
fmt.Println("删除广州后 cityMap1:", cityMap1)
|
||
|
||
/* * 2. 增加/修改元素
|
||
map[key] = value
|
||
key 不存在就是新增,key 存在就是修改
|
||
*/
|
||
cityMap1["深圳"] = "深圳是中国的科技创新中心"
|
||
fmt.Println("添加深圳后 cityMap1:", cityMap1)
|
||
|
||
/*
|
||
如何判断某个key是否存在
|
||
comok断言: value, ok := map[key]
|
||
常用场景: 有了后就不修改, 没有才添加
|
||
*/
|
||
value, ok := cityMap1["上海"]
|
||
if ok {
|
||
fmt.Println("上海存在,描述是:", value)
|
||
} else {
|
||
fmt.Println("上海不存在")
|
||
}
|
||
|
||
/*
|
||
map的遍历
|
||
range iterage -> (k/indev/..., v)
|
||
for key, value := range map {
|
||
}
|
||
*/
|
||
fmt.Println("== map的遍历 ==")
|
||
for key, value := range cityMap1 {
|
||
fmt.Printf("%s 的描述是: %s\n", key, value)
|
||
}
|
||
// 通常只需要 key 的场景, 对象修改
|
||
for key := range cityMap1 {
|
||
fmt.Printf("%s 的描述是: %s\n", key, cityMap1[key])
|
||
}
|
||
|
||
/*
|
||
map 是一种引用类型, 默认值是 nil, 通过指针 指向数据(key value)c存储区(bucket)
|
||
*/
|
||
fmt.Println("== map 是引用类型 ==")
|
||
m1 := map[string]int{"a": 1}
|
||
m2 := m1 // 共享底层数据
|
||
|
||
m2["b"] = 2
|
||
fmt.Println(m1) // map[a:1 b:2] m1也被修改
|
||
fmt.Println(m2) // map[a:1 b:2]
|
||
}
|
||
|
||
type Person struct {
|
||
Name string
|
||
Age int
|
||
}
|