go语言中的map学习笔记

集合 Map

1.1 什么是Map

map是go语言内置类型,如果有编程基础的人,相信可以很快理解map究竟是什么,它将value与key关联起来,可以用key检索。
Map是一种无序键值对的集合,key类似索引,指向数据的value。
Map基于hash实现,所以这也是它无序的原因。
Map是引用类型。

1.2 关于map的几个知识点

使用Map需要注意以下几点:

  • map无序,每次打印出来的map都会不一样。
  • map长度不固定,和slice一样,也是引用类型
  • 内置的len函数适用于map,返回map拥有key的数量。
  • map的key是所有可以用== 或者!=比较的类型,如布尔、整数、浮点、字符串等。所以数组、切片不能作为key
  • value是可以作为任意类型的,通过空接口,我们可以存储任意值,但是使用这种类型作为值时需要先做一次类型断言。
  • map 传递给函数的代价很小:在 32 位机器上占 4 个字节,64 位机器上占 8 个字节,无论实际上存储了多少数据。通过 key 在 map 中寻找值是很快的,比线性查找快得多,但是仍然比从数组和切片的索引中直接读取要慢 100 倍;所以如果你很在乎性能的话还是建议用切片来解决问题
  • map也可以用函数作为自己的值,这样可以用来做分支结构:key用来选择要执行的函数。
  • 不要使用new,永远用make来构造map。如果使用new分配一个对象,你会获得一个空引用指针。

1.3 map的使用

  1. 先声明再make

    var m map[string]string
    m = make(map[string]string,10)
    
  2. 声明的同时make

    var m = make(map[string]string,10)
    
  3. 声明并直接赋值

    var m map[string]string = map[string]string{"id": "01"}
    

来看一段代码:

  var m map[string]string //定义一个map
	m = make(map[string]string) 
	m2 := make(map[string]string)//简短写法

	m["a"] = "apple" //放入key和value
	m["b"] = "banana"

	value, ok := m["a"] //ok是看当前key是否存在返回布尔,value返回对应key的值
	if ok {
		fmt.Printf("exist key, value is %s \n", value)
	} else {
		fmt.Println("not exist")
	}

	value2, ok := m2["a"]
	if ok {
		fmt.Printf("exist key, value is %s \n", value2)
	} else {
		fmt.Println("not exist")
	}

结果如下:

exist key, value is apple not exist

not exist

1.4 遍历map

	var m map[string]string
	m = make(map[string]string)
	m["a"] = "apple"
	m["b"] = "banana"
	for key,value := range dict{ //取map中的值
      fmt.Println(key,"**********",value)
   }

运行结果:

b =====> banana

a =====> apple

1.5 删除map元素

var m map[string]string
	m = make(map[string]string)
	m["a"] = "apple"
	m["b"] = "banana"
	delete(m, "a") // 删除m里的key:a
	for key,value := range dict{ //取map中的值
     fmt.Println(key,"**********",value)
  }

运行结果:

b =====> banana

1.6 map与slice的使用

定义三个map,然后装进一个切片中,遍历切片。

  m1 := map[string]string{
		"name": "zhangsan",
		"id":   "01"}
	m2 := map[string]string{
		"name": "lisi",
		"id":   "02"}
	m3 := map[string]string{
		"name": "wangwu",
		"id":   "03"}

	slice := make([]map[string]string, 0, 3)
	slice = append(slice, m1)
	slice = append(slice, m2)
	slice = append(slice, m3)

	for _, val := range slice {
		fmt.Printf("name : %s, id : %s \n", val["name"], val["id"])
	}

运行结果:

name : zhangsan, id : 01

name : lisi, id : 02

name : wangwu, id : 03

1.7 关于map是引用类型

如果现在有一个map 叫m3, 然后我们再定义一个map m4, 我们让m4 = m3, 如果我们改掉m3里key的value的话,那m4会保持不变还是跟着m3一样改变里面的value呢?

很明显,会跟着m3一样改变。

m3 := map[string]string{
		"name": "wangwu",
		"id":   "03"}
m4 := m3
	fmt.Println(m4) //第一次打印里面的内容
	m3["name"] = "zhaoliu"
	fmt.Println(m4) //第二次打印里面的内容

结果如下:

map[id:03 name:wangwu]

map[id:03 name:zhaoliu]

1.8 map的排序

基本介绍

  • golang中没有一个专门的方法针对map的key进行排序
  • golang中map默认无序,也不是按照添加的顺序存放的,你每次遍历,得到的输出可能不一样.
  • golang中map的排序,是先将key进行排序,然后根据key值遍历输出即可

具体实现:TBD.

1.9 其他

map容量达到最大后, 再增加元素会自动扩容, 也就是说map会动态增长。

posted on 2020-03-05 22:00  长方形  阅读(409)  评论(0编辑  收藏  举报

导航