8.26Go之容器之Map(映射)

8.26Go之容器之Map(映射)

Go之Map的特点

  • map 是一种特殊的数据结构,一种元素对(pair)的无序集合

  • pair 对应一个 key(索引)和一个 value(值)

map在Java中也有一样的数据类型,但是必须要声明map的key类型和value类型

Map的概念

数据类型:

Map是引用类型

声明方式:

var mapname map[keytype]valuetype
  • mapname 为 map 的变量名。

  • keytype 为key类型。

  • valuetype 是key对应的value类型。

[keytype] 和 valuetype 之间允许有空格。

示例:

package main

import "fmt"

func main() {
/*声明三个Map*/
var mapList map [string] int
var mapAssigned map [string] int
mapCreated := make(map [string] float32)

/*往mapList中添加元素*/
mapList = map [string] int{"long": 18, "age": 22}

//因为mapAssigned的key类型和value类型和mapList一致,所以可以直接赋值
mapAssigned = mapList

//另一种对map赋值的方式
mapCreated["long"] = 3.1415926
mapCreated["age"] = 18
mapCreated["big"] = 19

//格式化输出值
fmt.Printf("Map List at "long" is :%d ", mapList["long"])
fmt.Printf("Map List at "age" is :%d ", mapList["age"])
fmt.Printf("Map Assigned "age" is :%d ", mapAssigned["age"])
fmt.Printf("Map Created "big" is :%f ", mapCreated["big"])
fmt.Printf("Map Created "big" is :%f ", mapCreated["long"])
}

代码分析:

  • mapLit 使用{key1: value1, key2: value2}的格式来初始化 map ,就像数组和结构体一样。

  • mapCreated 的创建方式mapCreated := make(map[string]float)等价于mapCreated := map[string]float{}

  • mapAssigned 是 mapList 的引用,对 mapAssigned 的修改也会影响到 mapLit 的值--->指针指向同一块内存区域

类似Java当中的:

package PracticeReview.StringChangeInt;

import java.util.HashMap;
import java.util.Map;

/**
* Map练习
* @since JDK 1.8
* @date 2021/08/26
* @author Lucifer
*/
public class MapPractice {
   public static void main(String[] args) {
       Map<String, String> map = new HashMap<String,String>();
       map.put("name", "Jun");
       map.put("age", "22");
       map.put("long", "18");
       System.out.println(map);
  }
}

Go的Map要注意的点:

  • 可以使用 make(),但不能使用 new() 来构造 map,如果错误的使用 new() 分配了一个引用对象,会获得一个空引用的指针,相当于声明了一个未初始化的变量并且取了它的地址

mapCreated := new(map[string]float)
mapCreated["key1"] = 4.5
/*
调用这个map的时候编译会报错
*/

Map容量

特点:

  • map 可以根据新增的 key-value 动态的伸缩,不存在固定长度或者最大限制

  • 也可以选择标明 map 的初始容量 capacity

初始Map容量声明格式:

make(map[keytype]valuetype, cap)

示例:

package main

import "fmt"

func main() {
/*声明一个预定义长度的map*/
mapValue := make(map [string] float32, 100)
mapValue = map [string] float32{
"C0": 16.35, "D0": 18.35, "E0": 20.60, "F0": 21.83,
"G0": 24.50, "A0": 27.50, "B0": 30.87, "A4": 440,
}

fmt.Println(mapValue)
}
/*
   出于性能的考虑,对于大的 map 或者会快速扩张的 map,即使只是大概知道容量,也最好先标明
*/

当 map 增长到容量上限的时候,如果再增加新的 key-value,map 的大小会自动加 1

用切片作为Map的值

Map的key对应一个Value,那么要对应多个Value的值就需要定义为 []int 类型或者其他类型的切片

因为Map本身是引用类型,所以Value值也可以是引用类型。

package main

import "fmt"

func main() {
/*声明一个Map映射*/
mapValue := make(map [string] int)

mapValue2 := make(map [int] *[]int)

intValue := []int{1,2,3,4,5,6}

mapValue2 = map [int] *[]int{
1: &intValue,
}
mapValue2[2] = &intValue
/*Map有两种赋值方式*/
/*
1、像mapValue = map [string] int{"age": 22}再value后接"{}"里面写key和value
2、像mapValue2[2] = &intValue这样,将value赋值给左边的key位--->"[]"里面写key
*/

mapValue = map [string] int{"age": 22}

fmt.Println(mapValue)
fmt.Println(mapValue2)
}
/*
   需要注意:
   1、Map里面添加的key和value要成对出现,而且用":"隔开不是",
   2、引用类型的value末尾需要加","
*/

Map元素的删除和清空

Go语言提供了一个内置函数 delete(),用于删除容器内的元素

传参数是"map","key"

delete(map, 键)
  • map 为要删除的 map 实例

  • 键为要删除的 map 中键值对的键。

示例:

package main

import "fmt"

func main() {
/*声明一个map*/
mapValue := map[string]int{}

/*为其赋值*/
mapValue["age"] = 22
mapValue["long"] = 18
mapValue["howlong"] = 16

/*打印map*/
fmt.Println(mapValue)

/*试用delete函数删除掉一个key*/
delete(mapValue, "howlong")

fmt.Println(mapValue)
}

清空 map 中的所有元素

Go语言中并没有为 map 提供任何清空所有元素的函数、方法,清空 map 的唯一办法就是重新 make 一个新的 map

遍历Map(访问map中的每一个键值对)

使用for range,即可遍历键又可遍历值

package main

import "fmt"

func main() {
/*声明一个mapPair*/
mapValue := map[string]int{}

/*添加值*/
mapValue["long"] = 18
mapValue["width"] = 20
mapValue["height"] = 22
mapValue["weight"] = 25

/*遍历key和value*/
for i, j := range mapValue {
fmt.Printf("key是%s,值是%d: ", i, j)
}
}

使用匿名变量,只遍历值

package main

import "fmt"

func main() {

/*声明一个mapPair*/
mapValue := map [string] int{}

/*添加值*/
mapValue["long"] = 18
mapValue["width"] = 20
mapValue["height"] = 22
mapValue["weight"] = 25

/*只遍历value*/
for _, k := range mapValue {
fmt.Printf("全部的值是%d ", k)
}
}

只遍历键

package main

import "fmt"

func main() {

/*声明一个mapPair*/
mapValue := map [string] int{}

/*添加值*/
mapValue["long"] = 18
mapValue["width"] = 20
mapValue["height"] = 22
mapValue["weight"] = 25

/*只遍历key*/
for l := range mapValue {
fmt.Printf("全部的key是%s ", l)
}
}

遍历特定顺序(先排序再遍历)

package main

import (
"fmt"
"sort"
)

func main() {

/*声明一个mapPair*/
mapValue := map [string] int{}

/*添加值*/
mapValue["long"] = 25
mapValue["width"] = 22
mapValue["height"] = 20
mapValue["weight"] = 18

/*声明一个切片*/
var srcSlice []string

//复制key到srcSlice当中
for h := range mapValue {
srcSlice = append(srcSlice, h)
}

//对切片排序
sort.Strings(srcSlice)

fmt.Println(srcSlice)
}
It's a lonely road!!!
原文地址:https://www.cnblogs.com/JunkingBoy/p/15191225.html