Go map用法必记

Go语言的map底层使用hash表实现

map初始化

  1. 字面量初始化
m := map[string]int{
	"jack": 100,
	"rose": 90,
}
  1. 内置函数make()初始化(指定容量可以有效减少内存分配的次数)
m := make(map[string]int, 10)
m["apple"] = 2
m["banana"] = 3

map增删改查

m := make([string]string, 10)
v, ok := m["apple"] //查询
if ok {
	m["apple"] = red  //如果存在,修改
}else{
	m["apple"] = green //如果不存在,新增
}
delete(m, "apple") //删除

空map

  1. len()可以查询map的长度,表示map中存储的键值对数
  2. 未初始化的map值为nil,在向值为nil的map添加元素时会触发panic
  3. 值为nil的map,长度与空map一致
  4. 操作值为nil的map没有意义,但是查询、删除操作不会报错
  5. delete(),没有返回值,在map为nil或者指定的键不存在的情况下,delete()不会报错,相当于空操作
var m1 map[string]int //值为nil的map
m2 := make(map[string]int) //空map
m3 := make(map[string]int, 10)

fmt.Println(m1==nil) //true
fmt.Println(m2==nil) //false
fmt.Println(m3==nil) //false

fmt.Println(m1["a"]==0) //true
fmt.Println(m2["a"]==0) //true
fmt.Println(m3["a"]==0) //true

fmt.Println(len(m1)) //0
fmt.Println(len(m2)) //0
fmt.Println(len(m3)) //0

delete(m1, "a") //不会报错

map类型的slice

假设我们想获取一个 map 类型的切片,我们必须使用两次 make() 函数,第一次分配切片,第二次分配 切片中每个 map 元素

mapSlice := make([]map[string]int, 8, 8)//只初始化了切片
fmt.Println(mapSlice[0]==nil) //true
fmt.Printf("mapSlice:%v\\n",mapSlice)
//mapSlice:[map[] map[] map[] map[] map[] map[] map[] map[]]

for i := range mapSlice {
   mapSlice[i] = make(map[string]int, 8) //初始化map
}

fmt.Println(mapSlice[0]==nil) //false
mapSlice[0]["apple"] = 100
fmt.Printf("mapSlice:%v\\n",mapSlice)
//mapSlice:[map[apple:100] map[] map[] map[] map[] map[] map[] map[]]

注意事项

  1. 初始化map时推荐使用内置函数make()并指定预估的容量
  2. 修改键值对时,需要先查询指定的键是否存在,否则map将创建新的键值对
  3. 查询键值对时,最好检查键是否存在,避免操作零值
  4. 避免并发读写map,如果需要并发读写map,则可以使用额外的锁(互斥锁、读写锁),也可以考虑使用标准库sync包中的sync.Map。

map排序

  1. map 默认是无序的,不管是按照 key 还是按照 value 默认都不排序
  2. 如果你想为 map 排序,需要将 key(或者 value)拷贝到一个切片,再对切片排序(使用 sort )
  3. 然后使用切片的 for-range 方法打印出所有的 key 和 value
barVal := map[string]int{"alpha": 34, "bravo": 56, "charlie": 23,
		"delta": 87, "echo": 56, "foxtrot": 12,
		"golf": 34, "hotel": 16, "indio": 87,
		"juliet": 65, "kili": 43, "lima": 98}

fmt.Println("unsorted:")
for k, v := range barVal {
	fmt.Printf("Key: %v, Value: %v / ", k, v)
}

keys := make([]string, len(barVal))
i := 0
for k, _ := range barVal {
	keys[i] = k
	i++
}
sort.Strings(keys)

fmt.Println()
fmt.Println("sorted:")
for _, k := range keys {
	fmt.Printf("Key: %v, Value: %v / ", k, barVal[k])
}

将 map 的键值对调

这里对调是指调换 key 和 value。如果 map 的值类型可以作为 key 且所有的 value 是唯一的,那么通过下面的方法可以简单的做到键值对调。

barVal := map[string]int{"alpha": 34, "bravo": 56, "charlie": 23,
		"delta": 87, "echo": 56, "foxtrot": 12,
		"golf": 34, "hotel": 16, "indio": 87,
		"juliet": 65, "kili": 43, "lima": 98}

invMap := make(map[int]string, len(barVal))
for k, v := range barVal {
	invMap[v] = k
}
fmt.Println("inverted:")
for k, v := range invMap {
	fmt.Printf("Key: %v, Value: %v / ", k, v)
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值