首页 > 编程语言 > 详细

Go语言 复合数据类型【集合map】

时间:2021-05-21 18:13:20      阅读:12      评论:0      收藏:0      [点我收藏+]

集合(Map)

1.1 什么是Map

map是go中的内置类型,它将一个值与一个键关联起来。可以使用相应的键检索值

Map是一种无序的键值对的集合。Map最重要的一点就是通过key来快速检索数据,key类似于索引,指向数据的值

Map是一种集合,所以我们可以向迭代数组金额切片那样迭代它。不过Map是无序的,我们无法决定它的返回顺序,这是因为Map是使用hash表来实现的,也是引用类型

使用map过程中需要注意的几点:

  • map是无序的,每次打印出来的map都会不一样,它不能通过index获取,而必须通过key获取
  • map的长度是不固定的,也就是和slice一样,也是一种引用类型
  • 内置的len函数同样适用于map,返回map拥有的key的数量
  • map的key可以是所有可比较的类型,如布尔型、整数型、浮点型、复杂型、字符串型......也可以键

1.2 Map的使用

1.2.1 使用make()创建map

  • 可以使用内建函数make,也可以使用map关键字来定义Map:
/* 声明变量,默认 map 是 nil */
var map_variable map[key_data_type]value_data_type

/* 使用 make 函数 */
map_variable := make(map[key_data_type]value_data_type)

1.2.2 map语法结构

1、创建map语法结构
	var map1 = map[key类型]value类型
	   此map为nil,无法直接使用

	var map2 = make(map[key类型]value类型)

	var map3 = mapp[key类型]value类型{key:value,key:value,key:value......}

2、	添加/修改map
    map[key] = value
        如果key不存在,就是添加数据
        如果key不存在,就是修改数据

3、 获取map数据
    map[key] ---> value
    
    value,ok := map[key]
       根据key获取对应的value值
            如果key存在,value就是对应的数据,ok为true
            如果key不存在,value就是值类型的默认值,ok为false
4、删除map数据 
    delete(map,key)
        如果key存在,就可以直接删除
        如果key不存在,删除失败,但对整个map也没有任何影响
5、获取map长度
    len()

注:
map也是一种引用类型,如果只有定义,没有创建,则为nil

如果不初始化 map,那么就会创建一个 nil map。nil map 不能用来存放键值对

每种数据类型的默认值:

int:0
float:0.0 --> 0
string: ""
array: [0000]

slice:nil  如果slice没有初始化,但是因为slice有底层数组,所以也是可以直接使用的
map:nil  空的map是不可以直接使用的

1.2.3 代码示例

  • 1、创建map示例
	//创建map
	var map1 map[int]string  //没有初始化,nil map
	var map2 = make(map[int]string)  //make本身就是创建,所以该map为已创建状态
	var map3 = map[string]int{"golang":01,"java":02,"vue":03,"python":04}  //声明时给了初始值,则会首先创建map,再讲键值对存进map

	//打印map
	fmt.Println(map1)   //map[]
	fmt.Println(map2)   //map[]
	fmt.Println(map3)   //map[golang:1 java:2 python:4 vue:3]

	//nil map无法分配数据
	//map1[1] = "hello"  //panic: assignment to entry in nil map (没有办法向一个nil map中分配数据)

	//测试map是否为空
	fmt.Println(map1 == nil)  //true
	fmt.Println(map2 == nil)  //false
	fmt.Println(map3 == nil)  //false

	//首先判断map是否为空,如果为空,则使用make创建map
	if map1 == nil{
		map1 = make(map[int]string)
	}
	fmt.Println(map1 == nil)  //false
  • 3、存储键值对到map中
    //map1[key] = value
	map1[1] = "hello"
	map1[2] = "world"
	map1[3] = "blockahin"
	map1[4] = "阆中"
	map1[5] = "golang"
	map1[6] = "杰胖"
	map1[7] = ""
  • 4、获取map数据
    //4、获取map数据,根据key获取对应的value值
	//根据key获取对应的value,如果key存在,获取数值;如果key不存在,获取的是value值类型的零值
	fmt.Println(map1)  //map[1:hello 2:world 3:blockahin 4:阆中 5:golang 6:杰胖]
	fmt.Println(map1[6])  //根据key为4,获取对应的value值

	//判断map的key是否为零值
	m1,ok := map1[40]
	if ok {
		fmt.Println("对应的数值是:",m1)
	}else {
		fmt.Println("操作的key不存在,获取到的是零值:",m1)
	}
  • 5、修改map数据
    //修改map数据
    //修改数据和存储数据是同样的语法,如果key不存在,则为存储map数据;如果key存在,则为修改map数据
	fmt.Println(map1)  //map[1:hello 2:world 3:blockahin 4:阆中 5:golang 6:杰胖 7:]
	map1[3] = "区块链"
	fmt.Println(map1)  //map[1:hello 2:world 3:区块链 4:阆中 5:golang 6:杰胖 7:]
  • 6、删除map数据
    //删除map数据
	 //删除map数据时,根据key进行删除,如果key存在,则将key删除;如果key不存在,则对整个map集合没有任何影响
	delete(map1,3)
	fmt.Println(map1)     //map[1:hello 2:world 4:阆中 5:golang 6:杰胖 7:]
	delete(map1,30)
	fmt.Println(map1)     //map[1:hello 2:world 4:阆中 5:golang 6:杰胖 7:]
  • 7、长度
	//长度
	fmt.Println(len(map1))
  • 完整代码示例
package main

import (
	"fmt"
)

func main()  {

	//1、创建map
	var map1 map[int]string  //没有初始化,nil map
	var map2 = make(map[int]string)  //make本身就是创建,所以该map为已创建状态
	var map3 = map[string]int{"golang":01,"java":02,"vue":03,"python":04}  //声明时给了初始值,则会首先创建map,再讲键值对存进map

	//打印map
	fmt.Println(map1)   //map[]
	fmt.Println(map2)   //map[]
	fmt.Println(map3)   //map[golang:1 java:2 python:4 vue:3]

	//2、nil map
	//测试map是否为空
	fmt.Println(map1 == nil)  //true
	fmt.Println(map2 == nil)  //false
	fmt.Println(map3 == nil)  //false

	//首先判断map是否为空,如果为空,则使用make创建map
	if map1 == nil{
		map1 = make(map[int]string)
	}
	fmt.Println(map1 == nil)  //false
	//3、存储键值对到map中
	//map1[key] = value
	map1[1] = "hello"
	map1[2] = "world"
	map1[3] = "blockahin"
	map1[4] = "阆中"
	map1[5] = "golang"
	map1[6] = "杰胖"
	map1[7] = ""

	//4、获取map数据,根据key获取对应的value值
	//根据key获取对应的value,如果key存在,获取数值;如果key不存在,获取的是value值类型的零值
	fmt.Println(map1)  //map[1:hello 2:world 3:blockahin 4:阆中 5:golang 6:杰胖]
	fmt.Println(map1[6])  //根据key为4,获取对应的value值

	//判断map的key是否为零值
	m1,ok := map1[40]
	if ok {
		fmt.Println("对应的数值是:",m1)
	}else {
		fmt.Println("操作的key不存在,获取到的是零值:",m1)
	}

	//5、修改map数据
    //修改数据和存储数据是同样的语法,如果key不存在,则为存储map数据;如果key存在,则为修改map数据
	fmt.Println(map1)  //map[1:hello 2:world 3:blockahin 4:阆中 5:golang 6:杰胖 7:]
	map1[3] = "区块链"
	fmt.Println(map1)  //map[1:hello 2:world 3:区块链 4:阆中 5:golang 6:杰胖 7:]

	 //6、删除map数据
	 //删除map数据时,根据key进行删除,如果key存在,则将key删除;如果key不存在,则对整个map集合没有任何影响
	delete(map1,3)
	fmt.Println(map1)     //map[1:hello 2:world 4:阆中 5:golang 6:杰胖 7:]
	delete(map1,30)
	fmt.Println(map1)     //map[1:hello 2:world 4:阆中 5:golang 6:杰胖 7:]

	//7、长度
	fmt.Println(len(map1))
}

1.3 Map的遍历

使用:for range

数组、切片:for range获取的是 index、value

map:for range获取的是 key、value

  • 遍历map
package main

import (
	"fmt"
)

func main()  {
map1 := make(map[int]string)
	map1[1] = "红孩儿"
	map1[2] = "牛魔王"
	map1[3] = "白骨精"
	map1[4] = "小钻风"
	map1[5] = "黄袍怪"
	map1[6] = "孔雀大明王"
	map1[7] = "白毛鼠"

	for k,v := range map1{
		fmt.Println(k,v)
	}
}	
  • 有序遍历连续key值的map
package main

import (
	"fmt"
)

func main()  {
	map1 := make(map[int]string)
	map1[1] = "红孩儿"
	map1[2] = "牛魔王"
	map1[3] = "白骨精"
	map1[4] = "小钻风"
	map1[5] = "黄袍怪"
	map1[6] = "孔雀大明王"
	map1[7] = "白毛鼠"

	for i := 1;i<=len(map1);i++{
		fmt.Println(i,"-->",map1[i])
	}
}	
  • 有序遍历不是连续key值的map
package main

import (
	"fmt"
	"sort"
)

func main()  {
	map1 := make(map[int]string)
	map1[1] = "红孩儿"
	map1[2] = "牛魔王"
	map1[3] = "白骨精"
	map1[4] = "小钻风"
	map1[5] = "黄袍怪"
	map1[6] = "孔雀大明王"
	map1[7] = "白毛鼠"
	
	//获取所有的key,取值后存储到切片
	keys := make([]int,0,len(map1))
	for k,_ := range map1{
		keys = append(keys,k)
	}
	fmt.Println(keys)


	//对key值进行排序
	//内置函数sort包下的排序方法
	sort.Ints(keys)
	fmt.Println(keys)
	for _,key := range keys{
		fmt.Println(key,"-->",map1[key])
	}

	//冒泡排序方法
	for i := 1;i<len(keys);i++ {
		for j := 0;j<len(keys)-1;j++ {
			if keys[j] > keys[j+1] {
				keys[j],keys[j+1] = keys[j+1],keys[j]
			}
		}
		}
	for i := 1;i<=len(keys);i++ {
		fmt.Println(i,"-->",map1[i])
	}
}
  • 对字符串值的key值进行有序排序
package main

import (
	"fmt"
	"sort"
)

func main()  {

	var map1 = map[string]int{"v神":185,"alice":170,"二狗":160,"bella":158,"ann":172}

	//获取所有的key,存储到切片或数组中
	keys := make([]string,0,len(map1))
	for k,_ := range map1{
		keys = append(keys,k)
	}
	fmt.Println(keys)

	//sort下的排序方法进行排序
	sort.Strings(keys)
	fmt.Println(keys)

	for _,key := range keys{
		fmt.Println(key,map1[key])
	}
}

1.4 Map结合Slicwe

1.4.1 代码示例

map和slice的组合使用

  • 1、创建map用于存储个人信息:name,age,sex,address
  • 2、每个map存储一个人的信息
  • 3、将这些map存入到slice中
  • 4、打印遍历输出
package main

import (
	"fmt"
)

func main()  {
    //创建map存储第一个人的信息
	var map1 = make(map[string]string)
	map1["name"] = "红孩儿"
	map1["age"] = "5"
	map1["sex"] = "男性"
	map1["address"] = "牛魔山"
	fmt.Println(map1)

    //创建map存储第二个人的信息
	var map2 = make(map[string]string)
	map2["name"] = "王二狗"
	map2["age"] = "30"
	map2["sex"] = "男性"
	map2["address"] = "北京市"
	fmt.Println(map2)

    //创建map存储第三个人的信息
	map3 :=map[string]string{"name":"李小芳","age":"24","sex":"女性","address":"高碑店村"}
	fmt.Println(map3)
    
    //将map存入到slice中
	var s1 = make([]map[string]string,0,3)
	s1 = append(s1,map1)
	s1 = append(s1,map2)
	s1 = append(s1,map3)
    
    //遍历切片
	for k,v := range s1{
		fmt.Printf("第%d个人的信息:\n",k+1)
		fmt.Printf("姓名:%s\n",v["name"])
		fmt.Printf("年龄:%s\n",v["age"])
		fmt.Printf("性别:%s\n",v["sex"])
		fmt.Printf("地址:%s\n",v["address"])
	}
}

1.5 Map是引用类型

1.5.1 map的数据类型

  • 1、数据类型:
    基本数据类型:int、float、string、bool

    复合数据类型:array、slice、map、function、pointer、struct...

      array:[size]数据类型
      slice:[]数据类型
      map:map[key的类型]value的类型
    
  • 2、存储特点:
    值类型(默认深拷贝):int、float、string、bool、array、struct

    引用类型(默认浅拷贝):slice、map、chan (注:使用make函数进行创建的,都是引用类型)

1.5.2 代码示例

package main

import (
	"fmt"
)

func main()  {

	//map数据类型
	map1 := make(map[int]string)  //map[int]string
	map2 := make(map[string]float64) //map[string]float64


	fmt.Printf("%T\n",map1)
	fmt.Printf("%T\n",map2)

	//map3中每一个key对应的值又是一个map
	map3 := make(map[string]map[string]string)  //map[string]map[string]string
	m1 := make(map[string]string)
	m1["name"] = "熊大"
	m1["age"] = "30"
	m1["salary"] = "20000"
	map3["ops"] = m1

	m2 := make(map[string]string)
	m2["name"] = "熊二"
	m2["age"] = "28"
	m2["salary"] = "25000"
	map3["dev"] = m2

	fmt.Println(map3)

	//map是引用类型,传递的是地址,map4与map5指向同一块内存空间
	map4 := make(map[string]string)
	map4["熊大"] = "运维工程师"
	map4["熊二"] = "开发工程师"
	map4["熊三"] = "产品经理"
	fmt.Println(map4)   //map[熊三:产品经理 熊二:开发工程师 熊大:运维工程师]
	map5 := map4
	fmt.Println(map5)  //map[熊三:产品经理 熊二:开发工程师 熊大:运维工程师]

	fmt.Printf("%p\n",map4)  //0xc000060510
	fmt.Printf("%p\n",map5)  //0xc000060510

	map5["熊大"] = "DBA"
	fmt.Println(map4)  //map[熊三:产品经理 熊二:开发工程师 熊大:DBA]
	fmt.Println(map5) //map[熊三:产品经理 熊二:开发工程师 熊大:DBA]

	fmt.Printf("%p\n",map4)  //0xc000060510
	fmt.Printf("%p\n",map5)  //0xc000060510
}

Go语言 复合数据类型【集合map】

原文:https://www.cnblogs.com/jemooner/p/14794584.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!