Golang:map的定义、操作、排序以及map切片

map概述

golang中的引用类型

与其他语言中的map类型基本相似,都是k-v形式的,k不可重复,元素是无序的,并且支持扩容

基本语法

var 变量名 map[keytype]valuetype

key可以是很多类型

bool、数字、string、指针、channel,还可以是只包含前面几种类型的 接口、结构体、数组

但是!!!slice、map、function是不可以作为map的key,因为无法使用 == 判断key是否相等

value的类型就没有特别的要求

声明

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

map的声明示例

package main

import "fmt"

//声明一个map变量
var map1 map[string]string

func main() {
	//第一种方式:先声明,再make
	fmt.Printf("map1=%v\n", map1)
	fmt.Printf("map1 address=%p\n", &map1)     //变量map1是有内存地址的
	fmt.Printf("map1==nil? %v\n", map1 == nil) //在没有make之前map1==nil为true成立,代表没有分配内存空间
	//使用map要先make
	map1 = make(map[string]string, 2) //分配了2个空间
	map1["LeoLee"] = "18"
	fmt.Printf("map1=%v, length=%d\n", map1, len(map1))
	map1["Lydia"] = "18"
	fmt.Printf("map1=%v, length=%d\n", map1, len(map1))
	map1["LeoLee"] = "26"
	fmt.Printf("map1=%v, length=%d\n", map1, len(map1))
	map1["Tony"] = "1" //map会自动扩容
	fmt.Printf("map1=%v, length=%d\n", map1, len(map1))

	//第二种方式:声明map变量的同时,make
	map2 := make(map[string]int) //这里不定义初始size,根据内置函数make的api说明,会分配一个默认起始大小:0
	fmt.Printf("map2=%v, length=%d\n", map2, len(map2))
	map2["a"] = 1
	map2["b"] = 2
	fmt.Printf("map2=%v, length=%d\n", map2, len(map2))

	//第三种方式:声明直接赋值
	map3 := map[int]string{
		1: "c",
		2: "d",
	}
	fmt.Printf("map3=%v, length=%d\n", map3, len(map3))
}

操作map

map的增删改查、以及循环遍历(map只能使用for range遍历):

package main

import "fmt"

func main() {
	//map删除元素,使用内置函数delete
	map1 := map[string]string{
		"a": "欸",
		"b": "币",
		"c": "西",
	}
	delete(map1, "a") // 若map为nil或无此元素,delete不进行操作
	delete(map1, "d")
	fmt.Printf("map1=%v, length=%d\n", map1, len(map1))
	//golang的map没有办法一次性删除所有的key-value,需要遍历删除
	for k, _ := range map1 {
		delete(map1, k)
	}
	fmt.Printf("map1=%v, length=%d\n", map1, len(map1))
	//或者对该map变量重新进行make初始化(指向新的内存地址),让该map变量对应的原来的引用对象成为垃圾。
	map1 = make(map[string]string)
	fmt.Printf("map1=%v, length=%d\n", map1, len(map1))

	//获取对应key的value
	map2 := map[string]string{
		"a": "欸",
		"b": "币",
		"c": "西",
	}
	val1, getRes1 := map2["a"]
	fmt.Printf("key:a, value:%s, getRes1:%v\n", val1, getRes1)
	val2, getRes2 := map2["d"]
	fmt.Printf("key:d, value:%s, getRes2:%v\n", val2, getRes2)

	//遍历,map的遍历只能使用for range方式
	for k, v := range map2 {
		fmt.Println(k, v)
	}
}

map切片

map切片类似于Java中的List<Map>或者是Array<Map>

package main

import "fmt"

//map切片,类似于Java中List<Map>
func main() {
	personSlice := make([]map[string]string, 2, 2)
	personSlice[0] = make(map[string]string)
	personSlice[0]["name"] = "LeoLee"
	personSlice[0]["age"] = "26"
	personSlice[1] = make(map[string]string)
	personSlice[1]["name"] = "Lydia"
	personSlice[1]["age"] = "29"
	//如果继续追加,会有越界
	/*personSlice[2] = make(map[string]string)
	personSlice[2]["name"] = "Lydia"
	personSlice[2]["age"] = "29"*/
	//所以需要使用slice的append,这样切片可以动态扩容
	personMap1 := make(map[string]string)
	personMap1["name"] = "Tony"
	personMap1["age"] = "30"
	personSlice = append(personSlice, personMap1)
	for _, m := range personSlice {
		fmt.Println(m)
	}
}

map的排序

由于Golang中没有提供原生的有序map,所以Golang中的有序map需要开发者自己实现,以下是一个对map进行有序输出的小例子:

package main

import (
	"fmt"
	"sort"
)

//map排序
func main() {
	//在老版本中,使用print输出map也会是无序的,新版本中变为升序
	//但是遍历map仍然是无序的
	map1 := map[int]string{
		3: "b",
		2: "a",
		6: "c",
		5: "e",
	}
	fmt.Println("map1=", map1)
	for k, v := range map1 {
		fmt.Printf("%d:%s\n", k, v)
	}
	map2 := make(map[string]string)
	map2["b"] = "1"
	map2["a"] = "4"
	map2["g"] = "2"
	map2["f"] = "8"
	fmt.Println("map2=", map2)
	for k, v := range map2 {
		fmt.Printf("%s:%s\n", k, v)
	}

	//对map进行排序
	/*1.先将map的key放入切片中
	2.对切片进行排序
	3.遍历切片,按照切片遍历的顺序获取key对应的value*/
	var keys1 []int
	for k, _ := range map1 {
		keys1 = append(keys1, k)
	}
	fmt.Printf("keys1=%v\n", keys1)
	//使用sort包下的Ints函数,Ints函数将会把传入的int类型切片按照递增顺序排序
	sort.Ints(keys1)
	fmt.Printf("keys1=%v\n", keys1)
	for _, key := range keys1 {
		val, _ := map1[key]
		fmt.Println(key, ":", val)
	}
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值