【Golang】第七弹----map

笔上得来终觉浅,绝知此事要躬行

🔥 个人主页:星云爱编程

🔥 所属专栏:Golang

🌷追光的人,终会万丈光芒

🎉欢迎大家点赞👍评论📝收藏⭐文章

1基本介绍

Go语言中的 map 是一种无序的键值对集合,类似于其他语言中的字典或哈希表。它通过键(key)来快速查找对应的值(value),键必须是唯一的,而值可以重复。

2.map的基本特性

  1. 键值对存储 :存储的数据是键值对形式, key: value
  2. 无序性 :遍历map时,顺序是不固定的
  3. 动态大小 :map的大小可以动态增长
  4. 引用类型 :map是引用类型,传递时传递的是引用

3.map的声明

基本语法:

Go 复制代码
var map变量名 map[keyType]ValueType

说明:

1.key可以是什么类型?

key可以为多种类型:整数型,浮点型,bool型,string,指针,channel,还可以是只包含前面几种类型的接口,结构体,数组;key一般为int,string

注意:slice,map和function不能用作key的类型,因为它们无法用==来判断

2.value可以是什么类型

value的类型和key的类型基本一样,通常为数字(整数、浮点数),string,map,struct

3.声明举例

Go 复制代码
	var a map[int]string
	var b map[string]string
	var c map[string]int

注意:声明是不会分配内存的,初始化需要make分配内存后才能赋值和使用

如下诉代码将会报错:

Go 复制代码
	var m map[string]int
	m["jack"]=10
	fmt.Println(m)

说明:

  • map在使用前一定要make
  • map的key是不能重复的,如果重复了,则以覆盖的形式更换对应的value
  • map的value是可以相同的
  • map的key-value是无序的

4.map的使用

第一种方式:

Go 复制代码
var a map[string]string
a=make(map[string]string,10)
a["name"]="jack"
a["age"]="111"

第二种方式:

Go 复制代码
stu:=make(map[string]string)
stu["stu1"]="jack"
stu["stu2"]="tom"

第三种方式:

Go 复制代码
var stu map[string]string=map[string]string{
        "stu1":"jack",
        "stu2":"tom",
}
Go 复制代码
 stu :=map[string]string{
        "stu1":"jack",
        "stu2":"tom",
}

5.map的增删查改操作

1.map增加和更新

Go 复制代码
map["key"]=value

说明:如果key不存在,就是增加,如果key存在即是修改

2.map删除

Go 复制代码
delete(map,"key")

说明:

  • delete是一个内置函数,如果key存在,就删除该key-value;若key不存在,则不进行操作,也不会报错
  • 如果我们要删除map的所有值,没有一个专门的方法一次删除,可以遍历map,逐个删除;或者map=make(...),make一个新的,让原来的成为垃圾,被gc回收

3.map查找

Go 复制代码
value, exists := m[key]

说明:如果m[key]存在,则exists为true,反之为false

4.案例

Go 复制代码
package main

import "fmt"

func main() {
    // 创建一个 map
    m := make(map[string]int)

    // 1. 增加元素
    m["apple"] = 1
    m["banana"] = 2
    fmt.Println("增加元素后:", m)

    // 2. 查找元素
    value, exists := m["apple"]
    if exists {
        fmt.Println("查找元素: apple ->", value)
    } else {
        fmt.Println("未找到元素: apple")
    }

    // 3. 修改元素
    m["banana"] = 3
    fmt.Println("修改元素后:", m)

    // 4. 删除元素
    delete(m, "banana")
    fmt.Println("删除元素后:", m)
}

6.map的遍历

在 Go 语言中, map 的遍历操作可以通过for- range实现。

案例:

Go 复制代码
package main

import "fmt"

func main() {
    // 创建一个 map
    m := map[string]int{
        "apple":  1,
        "banana": 2,
        "cherry": 3,
    }

    // 遍历 map
    for key, value := range m {
        fmt.Printf("Key: %s, Value: %d\n", key, value)
    }
}

说明:

  • for range 语法 : for key, value := range m 用于遍历 map , key 是键, value 是值。
  • map 的遍历顺序是随机的,因为 map 是无序的。
  • 如果只需要键或值,可以使用 _ 忽略不需要的部分。

7.map的长度

在 Go 语言中, map 的长度可以通过内置函数 len 来获取。

案例:

Go 复制代码
package main

import "fmt"

func main() {
    // 创建一个 map
    m := map[string]int{
        "apple":  1,
        "banana": 2,
        "cherry": 3,
    }

    // 获取 map 的长度
    length := len(m)
    fmt.Println("map 的长度:", length)
}

说明:

  • len 函数 : len(m) 返回 map 中键值对的数量。
  • 空 map :如果 map 为空, len(m) 返回 0 。
  • nil map :如果 map 是 nil , len(m) 也返回 0 。
  • 并发安全 : len 函数在并发环境下是安全的,但如果在遍历或修改 map 的同时调用 len ,可能会导致数据竞争,需要使用同步机制(如 sync.Mutex )来保护。
  • 性能 : len 函数的时间复杂度是 O(1),因为它只是返回 map 的内部计数器。

例如:

Go 复制代码
package main

import "fmt"

func main() {
    // 创建一个空 map
    m := make(map[string]int)
    fmt.Println("空 map 的长度:", len(m)) // 输出: 0

    // 添加元素
    m["apple"] = 1
    m["banana"] = 2
    fmt.Println("添加元素后 map 的长度:", len(m)) // 输出: 2

    // 删除元素
    delete(m, "apple")
    fmt.Println("删除元素后 map 的长度:", len(m)) // 输出: 1

    // nil map
    var nilMap map[string]int
    fmt.Println("nil map 的长度:", len(nilMap)) // 输出: 0
}

8.map切片

在 Go 语言中, map 切片是指一个切片,其中每个元素都是一个 map 。这种数据结构常用于需要存储多个 map 的场景。

使用案例:

Go 复制代码
package main

import "fmt"

func main() {
    // 定义一个 map 切片
    var mapSlice []map[string]int

    // 初始化 map 切片
    mapSlice = make([]map[string]int, 3) // 创建一个长度为 3 的切片
    for i := range mapSlice {
        mapSlice[i] = make(map[string]int) // 初始化每个 map
    }

    // 添加元素
    mapSlice[0]["apple"] = 1
    mapSlice[1]["banana"] = 2
    mapSlice[2]["cherry"] = 3

    // 遍历 map 切片
    for i, m := range mapSlice {
        fmt.Printf("mapSlice[%d]: %v\n", i, m)
    }
}
Go 复制代码
package main
import "fmt"

func main(){
	var Stu []map[string]string
	Stu=make([]map[string]string,2)
	//增加学生信息
	if Stu[0]==nil{
		Stu[0]=make(map[string]string,2)
		Stu[0]["name"]="欣欣"
		Stu[0]["age"]="19"
	}
	if Stu[1]==nil{
		Stu[1]=make(map[string]string,2)
		Stu[1]["name"]="依依"
		Stu[1]["age"]="18"
	}

	fmt.Println(Stu)

}

说明:

  • 定义 map 切片 : var mapSlice []map[string]int 定义了一个 map 切片,其中每个元素都是一个 map[string]int 。
  • 初始化 map 切片 :使用 make([]map[string]int, 3) 创建一个长度为 3 的切片,然后遍历切片,为每个元素初始化一个 map 。
  • 添加元素 :通过 mapSlice[i][key] = value 向每个 map 中添加键值对。
  • 遍历 map 切片 :使用 for range 遍历 map 切片,并输出每个 map 的内容。

注意事项:

  • 初始化 : map 切片中的每个 map 需要单独初始化,否则会引发运行时错误( nil map )。
  • 动态扩展 : map 切片可以动态扩展,使用 append 添加新的 map 。
  • 并发安全 :如果多个 goroutine 同时操作 map 切片,需要使用同步机制(如 sync.Mutex )来保护。

动态扩展:

Go 复制代码
package main

import "fmt"

func main() {
    // 定义一个 map 切片
    var mapSlice []map[string]int

    // 动态添加 map
    newMap := map[string]int{"orange": 4}
    mapSlice = append(mapSlice, newMap)

    // 遍历 map 切片
    for i, m := range mapSlice {
        fmt.Printf("mapSlice[%d]: %v\n", i, m)
    }
}

9.map排序

介绍:

(1)Go 中没有专门的方法对map的key进行排序;

(2)Go 中的map默认是无序的,每次遍历输出的顺序是随机的;

(3)Go 中map的排序,是先将key进行排序,然后根据key值遍历输出。

案例:对键排序

Go 复制代码
package main

import (
    "fmt"
    "sort"
)

func main() {
    m := map[string]int{
        "apple":  3,
        "banana": 1,
        "cherry": 2,
    }

    // 获取所有键
    keys := make([]string, 0, len(m))
    for k := range m {
        keys = append(keys, k)
    }

    // 对键排序
    sort.Strings(keys)

    // 按排序后的键输出
    for _, k := range keys {
        fmt.Printf("%s: %d\n", k, m[k])
    }
}

说明:

  • 提取 map 的所有键到切片中。
  • 使用 sort.Strings 对键排序。
  • 按排序后的键输出对应的值。

案例2:对值排序

Go 复制代码
package main

import (
    "fmt"
    "sort"
)

func main() {
    m := map[string]int{
        "apple":  3,
        "banana": 1,
        "cherry": 2,
    }

    // 定义一个结构体用于存储键值对
    type kv struct {
        Key   string
        Value int
    }

    // 将 map 转换为切片
    var kvs []kv
    for k, v := range m {
        kvs = append(kvs, kv{k, v})
    }

    // 对值排序
    sort.Slice(kvs, func(i, j int) bool {
        return kvs[i].Value < kvs[j].Value
    })

    // 按排序后的值输出
    for _, kv := range kvs {
        fmt.Printf("%s: %d\n", kv.Key, kv.Value)
    }
}

说明:

  • 定义一个结构体 kv 存储键值对。
  • 将 map 转换为 kv 切片。
  • 使用 sort.Slice 对值排序。
  • 按排序后的值输出对应的键。

10.map的使用细节

(1)map是引用类型,遵守引用类型传递的机制,在一个函数接受map并修改后,会直接修改原来的map;

例子:

Go 复制代码
package main

import "fmt"

// 修改 map 的函数
func modifyMap(m map[string]int) {
    m["apple"] = 10
    m["banana"] = 20
}

func main() {
    // 创建一个 map
    m := map[string]int{
        "apple":  1,
        "banana": 2,
    }

    fmt.Println("修改前:", m)
    modifyMap(m)
    fmt.Println("修改后:", m)
}

(2)map的容量满后,继续往map中添加元素,map会自动扩容,并不会发生panic,也就是说map能动态地增长键值对;

案例:

Go 复制代码
package main

import "fmt"

func main() {
    // 创建一个初始容量较小的 map
    m := make(map[int]int, 2)

    // 添加元素,观察 map 的动态扩容
    for i := 0; i < 10; i++ {
        m[i] = i * 10
        fmt.Printf("添加元素: %d -> %d, map 长度: %d\n", i, m[i], len(m))
    }
}

(3)map的value经常使用struct类型,更适合管理复杂的数据。

结语

感谢您的耐心阅读,希望这篇博客能够为您带来新的视角和启发。如果您觉得内容有价值,不妨动动手指,给个赞👍,让更多的朋友看到。同时,点击关注🔔,不错过我们的每一次精彩分享。若想随时回顾这些知识点,别忘了收藏⭐,让知识触手可及。您的支持是我们前进的动力,期待与您在下一次分享中相遇!

路漫漫其修远兮,吾将上下而求索。

相关推荐
yang_love101133 分钟前
Spring Boot 中的 @ConditionalOnBean 注解详解
java·spring boot·后端
hhw1991121 小时前
c#知识点补充3
开发语言·c#
Antonio9151 小时前
【Q&A】观察者模式在QT有哪些应用?
开发语言·qt·观察者模式
Pandaconda1 小时前
【后端开发面试题】每日 3 题(二十)
开发语言·分布式·后端·面试·消息队列·熔断·服务限流
mqwguardain1 小时前
python常见反爬思路详解
开发语言·python
鱼樱前端2 小时前
mysql事务、行锁、jdbc事务、数据库连接池
java·后端
lmy3477712322 小时前
东软鸿蒙C++开发面经
开发语言·c++
Adellle2 小时前
MySQL
数据库·后端·mysql
hakesashou2 小时前
python多线程和多进程的区别有哪些
java·开发语言·jvm
每次的天空2 小时前
项目总结:GetX + Kotlin 协程实现跨端音乐播放实时同步
android·开发语言·kotlin