第13节 Go中的map

138 阅读3分钟

map是一种key-value的数据结构,类似于Java中的Map集合。mapkey-value 是无序的,也不是按照添加顺序存放的,你每次遍历得到的结果顺序可能都不一样,且key不能重复,如果重复了就以最新的 key 为准。

1. map 的定义

1.1 基本语法

var 变量名称 map[key数据类型]value数据类型

  • key的数据类型: bool 、数字、string、指针、管道、接口、结构体、数组。但是通常使用int和string 类型作为key。key不能是切片、map 和 函数,因为它们没法用 == 来判断。
  • value可以是符合 golang 语法规则的数据类型。

1.2 map 的声明示例

map在声明后不会分配内存,需要先使用 make 函数初始化分配内存以后才能赋值和使用

var a map[string]string
var b map[string]int
var c map[int]string
var d map[string]map[string]string // 相当于Java中 Map<String,Map<String,String>>

1.2.1 声明方式一

package main

import "fmt"

func main() {
	var m map[string]string = make(map[string]string,10)
	m["1"] = "A"
	m["2"] = "B"
	// map[1:A 2:B]
	fmt.Println(m)
}

1.2.2 声明方式二

package main

import "fmt"

func main() {
	cityMap := map[string]string{
		"a" : "北京",
		"b" : "上海",
		"c" : "西安",
	} 
	cityMap["d"] = "商洛"
	// map[a:北京 b:上海 c:西安 d:商洛]
	fmt.Println(cityMap)
}

2. map的增删改查操作

2.1 新增修改

map[key] = value如果key不存在就是新增,如果key存在就是修改

package main

import "fmt"

func main() {
	cityMap := map[string]string{
		"a" : "北京",
		"b" : "上海",
		"c" : "西安",
	} 
	cityMap["d"] = "商洛"
	cityMap["a"] = "长沙"
	// map[a:长沙 b:上海 c:西安 d:商洛]
	fmt.Println(cityMap)
}

2.2 删除元素

func delete(m map[Type]Type1, key Type)

内置函数delete按照指定的键将元素从map中删除。若m为nil或无此元素,delete不进行操作。

2.3 查找元素

package main

import "fmt"

func main() {
	cityMap := map[string]string{
		"a" : "北京",
		"b" : "上海",
		"c" : "西安",
	} 
	cityMap["d"] = "商洛"
	cityMap["a"] = "长沙"
	// map[a:长沙 b:上海 c:西安 d:商洛]
	fmt.Println(cityMap)
        
        // 查找map中的元素
	val,res := cityMap["a"]
	if res {
		fmt.Printf("key存在,res=%v,val=%v\n", res, val)
	} else {
		fmt.Printf("key不存在,res=%v,val=%v\n", res, val)
	}
}

2.3 遍历和长度

  • map 遍历使用 for-range
  • map 长度使用内置函数 len

2.4 map排序

golangmap的排序,是先将key进行排序,然后遍历key获取value

  • (1)将 map 的 key 放入到 数组切片中
  • (2)对数组切片排序
  • (3)遍历数组切片,然后输出 map 值
package main

import "fmt"
import "sort"

func main() {
	m := map[int]string { 
		100 : "纽约", 
		23 : "伦敦",  
		34 : "香港", 
		1 : "西安", 
		5 : "伊犁",
	}

	var keys []int
	for key,_ := range m {
		keys = append(keys, key)
	}
        // [100 23 34 1 5]
	fmt.Println(keys)
	sort.Ints(keys)
	// [1 5 23 34 100]
	fmt.Println(keys)

	for _,v := range keys {
		fmt.Printf("key = %v, val = %v\n",v, m[v])
	}
}

image.png

3. map 切片

数据类型是map的切片,我们称为map切片,这样map数据就可以动态变化了

var m []map[int]int
package main

import "fmt"

func main() {
	 // map切片声明方,可以理解成 Java 中的 List<Map<String,String>>,初始化长度为 2
	 var mapSlice []map[string]string = make([]map[string]string, 2)
	 
	 if(mapSlice[0] == nil) {
		mapSlice[0] = map[string]string {
			"cityId" : "2",
			"cityName" : "伦敦",
		}
	 }

	 if(mapSlice[1] == nil) {
		mapSlice[1] =  make(map[string]string, 2)
		mapSlice[1]["cityId"] = "3"
		mapSlice[1]["cityName"] = "香港"
	 }

	 // 声明一个 map
	 map2 := map[string]string {
	 	"cityId" : "1",
	 	"cityName" : "西安",
 	}

	mapSlice = append(mapSlice, map2)
	// [map[cityId:1 cityName:西安] map[cityId:3 cityName:香港] map[cityId:1 cityName:西安]]
	fmt.Println(mapSlice)
}

4. map使用细节

  • map 是引用类型,遵守引用类型传递机制,当一个函数接收map参数后,这个参数被修改,会直接修改原来的 map
  • map 能动态扩容,这点和数组是有区别的,数组一旦声明长度就是固定的,不能动态变化