3.10 Go Map哈希表

map是key-value类型数据结构,读作(哈希表、字典),是一堆未排序的键值对集合。

map是引用类型,使用make函数或者初始化表达式创建。

map的key必须是支持相等运算符==!=的类型,如int、bool、channel、string、pointer、array、sruct、interface。

通常map的key是int、string

map的value可以是任意类型,没有限制,通常是int、float、string、struct

2. map声明

package main

import "fmt"

func main() {
/*
map声明语法
var 变量名 map[keytype]valuetype var m1 map[string]string
var m2 map[int]string
var m3 map[int]map[string]string//map的value又是map 注意map声明不会分配内存,必须make初始化才可以使用
*/ //声明map方式一
//make函数可以合理申请一大块内存,避免后续扩张时性能问题
var m1 map[string]string
//标注map的初始容量为10
m1 = make(map[string]string, 10)
m1["一号"] = "大狗子"
m1["二号"] = "二狗子"
fmt.Println(m1) //声明方式二
m2 := make(map[string]string)
m2["男"] = "小黑"
m2["女"] = "小女"
fmt.Println(m2) //声明方式三
m3 := map[string]string{
"坦克": "德玛西亚",
"射手": "伊泽瑞尔",
"辅助": "星女",
}
m3["打野"] = "赵信"
fmt.Println(m3)
}

3. map增删改查

访问不存在的键值,默认返回零值,不会引发错误。

推荐使用ok-idiom模式,如: val, ok := m1["k4"]

package main

import "fmt"

func main() {
m1 := map[string]string{"k1": "v1", "k2": "v2"}
fmt.Printf("m1值:%v\n", m1) //map插入值
m1["k3"] = "v3"
fmt.Printf("插入后m1值:%v\n", m1) //map修改值
m1["k1"] = "v11111"
fmt.Printf("修改k1值后:%v\n", m1) //map查找值
val, ok := m1["k4"]
if ok {
fmt.Printf("k4的值是:%v\n", val)
} //长度: 获取键值对数量
m1Len := len(m1)
fmt.Printf("m1长度:%v\n", m1Len) //判断key是否存在
if val, ok := m1["k4"]; !ok {
fmt.Printf("此key不存在\n")
} else {
fmt.Printf("此key的值:%v\n", val)
} //删除map的key,如key不存在,delete不进行操作
//delete函数按指定的键,将元素从映射中删除
//一次性删除所有key可以遍历下,逐个删除
//也可以重新make新map,让原本map被gc回收
if _, ok := m1["k3"]; ok {
delete(m1, "k3")
fmt.Printf("已删除m1中的k3\n")
} else {
fmt.Printf("无法删除,此key不存在")
}
fmt.Printf("此时m1的值:%v\n", m1)
}

4. map遍历

使用for-range结构遍历

package main

import "fmt"

func main() {
//循环性生成10个key的map
m1 := make(map[int]int)
for i := 0; i < 10; i++ {
m1[i] = i + 1
fmt.Printf("m1的key:%v value:%v\n", i, m1[i])
}
fmt.Println(m1)
fmt.Println("--分割线--")
//循环遍历map的值
for k, v := range m1 {
fmt.Printf("m1的key:%v m1的值%v\n", k, v)
}
}

遍历复杂map

map的value又是map

package main

import "fmt"

func main() {
//make初始化第一层map,分配内存
stuMap := make(map[string]map[string]string)
//第二层map初始化
stuMap["stu01"] = make(map[string]string)
stuMap["stu01"]["名字"] = "大狗子"
stuMap["stu01"]["年纪"] = "18" //切记,map必须make后方可使用
stuMap["stu02"] = make(map[string]string)
stuMap["stu02"]["名字"] = "二麻子"
stuMap["stu02"]["年纪"] = "17" fmt.Println(stuMap) //取出所有学生的信息
for k, v := range stuMap {
fmt.Printf("k值是学生:%v v值是学生信息:%v\n", k, v)
//k1是键,v1是值
for k1, v1 := range v {
fmt.Printf("\tk1:%v v1:%v\n", k1, v1)
}
fmt.Println()
}
}

5. map切片

声明一个切片(slice),并且这个切片的类型是map,这就被称作slice of map,map切片,这样map的个数就可以动态变化了。

package main

import "fmt"

func main() {
//声明map切片,
// 默认值 [map[] map[] map[] map[] map[]]
sliceMap := make([]map[string]string, 5)
for i := 0; i < 5; i++ {
//map必须初始化再用,遍历初始化
sliceMap[i] = make(map[string]string)
}
sliceMap[0]["名字"] = "张飞"
sliceMap[1]["性别"] = "不男不女"
sliceMap[2]["体重"] = "三百斤"
fmt.Println(sliceMap)
fmt.Printf("容量:%v,长度:%v\n", cap(sliceMap), len(sliceMap)) //动态扩容map切片,用append函数
newSliceMap := map[string]string{
"姓名": "狗子",
"爱好": "吃包子",
}
//append函数进行切片扩容,动态增加
sliceMap = append(sliceMap, newSliceMap)
fmt.Println(sliceMap)
fmt.Printf("容量:%v,长度:%v\n", cap(sliceMap), len(sliceMap))
}

6. map排序

map默认是无序的,每次遍历都是不同的结果

package main

import "fmt"

func main() {
//无须的map
m1 := make(map[int]int)
for i := 0; i < 10; i++ {
m1[i] = i + 1
}
//遍历结果无序
for k, v := range m1 {
fmt.Println(k, v)
}
}

通过索引排序取值

package main

import "fmt"

func main() {
m1 := map[int]string{
1: "红孩儿",
2: "孙悟空",
3: "银角大王",
4: "金角大王",
}
//无序
// for k, v := range m1 {
// fmt.Println(k, v)
// }
//通过索引,有序取值
for i := 1; i <= len(m1); i++ {
fmt.Println(i, m1[i])
}
}

sort包排序

golang没有针对map的key排序的方法。

必须先对key排序,然后根据key值就可以输出排序后的结果

调用sort包函数进行排序

sort.Strings

sort.Ints

package main

import (
"fmt"
"sort"
) func main() {
//定义一个m map变量
m := map[string]string{"q": "q", "w": "w", "e": "e", "r": "r", "t": "t", "y": "y"}
fmt.Println(m)
//定义一个 string类型切片
var slice []string
//循环遍历map,取出所有的key和value
for k, _ := range m {
//循环将key添加到切片中
slice = append(slice, k)
}
fmt.Printf("切片slice值 : %v\n", slice)
//调用排序包,对切片进行排序,按照字母顺序排序
sort.Strings(slice[:])
fmt.Printf("排序后 切片slice值 : %v\n", slice)
for _, v := range slice {
fmt.Printf("排序后 m[%v]=%v\n", v, m[v])
}
}

7. map使用细节

1)map是引用类型,遵循引用类型传递的机制,在函数接收map参数,对map修改是直接操作原本的map。

package main

import "fmt"

func modify(m map[string]string) {
m["名字"] = "狗子" }
func main() {
//map是引用类型,遵循引用引用类型传递
m1 := make(map[string]string)
m1["名字"] = "傻子"
m1["年纪"] = "十八"
fmt.Println(m1)
modify(m1) //直接对m1进行修改,说明是引用类型
fmt.Println(m1)
}

2)map可以自动扩容,动态增长。

package main

import "fmt"

func main() {
//初始化m1,限制容量3
m1 := make(map[int]int, 3)
for i := 0; i < 10; i++ {
m1[i] = i + i
}
fmt.Println(m1)
fmt.Printf("m1元素个数:%v", len(m1))
}

3)map的value也可以是struct类型,适合更复杂的数据

package main

import "fmt"

type Stu struct {
Name string
Age int
Address string
} func main() {
//map的value可以为更复杂的struct结构体类型
//map的key是学号
//map的value是结构体{姓名、年纪、住址}
students := make(map[int]Stu, 10)
//初始化结构体,不需要填写key,顺序value即可
stu1 := Stu{"alex", 1000, "沙河"}
stu2 := Stu{"武沛奇", 999, "于辛庄"}
students[1] = stu1
students[2] = stu2
fmt.Println(students)
//遍历map,取出学生信息
for k, v := range students {
fmt.Printf("学生编号%v\n", k)
fmt.Printf("学生姓名%v\n", v.Name)
fmt.Printf("学生年纪%v\n", v.Age)
fmt.Printf("学生住址%v\n", v.Address)
fmt.Println("--------")
}
}

4)函数len返回键值对数量,cap不适用map类型。

5)因内存访问安全和哈希算法等因素,字典设计是not addressable,不得直接修改value成员(struct或array)

6)mymap["age"]+=1此代码报错

7)mymap["age"]++ 相当于mymap["age"]=mymap["age"]+1 ,此代码正确,mymap["age"]返回的是指针

3.10 Go Map哈希表的更多相关文章

  1. Junit 注解 类加载器 .动态代理 jdbc 连接池 DButils 事务 Arraylist Linklist hashset 异常 哈希表的数据结构,存储过程 Map Object String Stringbufere File类 文件过滤器_原理分析 flush方法和close方法 序列号冲突问题

    Junit 注解 3).其它注意事项: 1).@Test运行的方法,不能有形参: 2).@Test运行的方法,不能有返回值: 3).@Test运行的方法,不能是静态方法: 4).在一个类中,可以同时定 ...

  2. 理解Golang哈希表Map的元素

    目录 概述 哈希函数 冲突解决 初始化 结构体 字面量 运行时 操作 访问 写入 扩容 删除 总结 在上一节中我们介绍了 数组和切片的实现原理,这一节会介绍 Golang 中的另一个集合元素 - 哈希 ...

  3. stl vector、红黑树、set、multiset、map、multimap、迭代器失效、哈希表(hash_table)、hashset、hashmap、unordered_map、list

    stl:即标准模板库,该库包含了诸多在计算机科学领域里所常用的基本数据结构和基本算法 六大组件: 容器.迭代器.算法.仿函数.空间配置器.迭代适配器 迭代器:迭代器(iterator)是一种抽象的设计 ...

  4. Freemarker 中的哈希表(Map)和序列(List)

    freemarlker中的容器类型有: 哈希表:是实现了TemplateHashModel或者TemplateHashModelEx接口的java对象,经常使用的实现类是SimpleHash,该类实现 ...

  5. [CareerCup] 8.10 Implement a Hash Table 实现一个哈希表

    8.10 Design and implement a hash table which uses chaining (linked lists) to handle collisions. 这道题让 ...

  6. [CareerCup] 13.2 Compare Hash Table and STL Map 比较哈希表和Map

    13.2 Compare and contrast a hash table and an STL map. How is a hash table implemented? If the numbe ...

  7. 哈希,哈希表,哈希Map

    数组: 数组存储区间是连续的,占用内存严重,故空间复杂的很大.但数组的二分查找时间复杂度小,为O(1):数组的特点是:寻址容易,插入和删除困难: 链表: 链表存储区间离散,占用内存比较宽松,故空间复杂 ...

  8. 哈希表(Hash Map)

    今天第一次做Leetcode用到了散列表,之前学的数据结构的内容都忘了,正好趁热打铁补一补. 摘自其他博客的一个整合. 一.哈希表简介 数据结构的物理存储结构只有两种:顺序存储结构和链式存储结构(像栈 ...

  9. C++ STL中哈希表Map 与 hash_map 介绍

    0 为什么需要hash_map 用过map吧?map提供一个很常用的功能,那就是提供key-value的存储和查找功能.例如,我要记录一个人名和相应的存储,而且随时增加,要快速查找和修改: 岳不群-华 ...

随机推荐

  1. RSA,AES加解密算法的实现

    目录 Python实现RSA公钥加密算法 RSA公钥加密算法原理 RSA算法的Python实现 AES加解密算法实现 AES加解密算法原理 AES加解密算法Python实现 参考文献 Python实现 ...

  2. 使用3种协议搭建本地yum仓库

    关闭防火墙和selinux [root@qls yum.repos.d]# systemctl stop firewalld (stop,start,disable,enable) [root@qls ...

  3. json序列化字符串后,配置枚举类型显示数值而不是名称

    2019独角兽企业重金招聘Python工程师标准>>> 经常有这么一个需求,实体类里面用到枚举常量,但序列化成json字符串时.默认并不是我想要的值,而是名称,如下 类 @Data ...

  4. 洛谷P3018 [USACO11MAR]树装饰Tree Decoration

    洛谷P3018 [USACO11MAR]树装饰Tree Decoration树形DP 因为要求最小,我们就贪心地用每个子树中的最小cost来支付就行了 #include <bits/stdc++ ...

  5. Xapian实战(一):环境搭建 + 简介

    1. 参考资料 http://xapian.org/docs/install.html Xapian的存储系统.性能以及检索模型等 2. 安装 1) xapian # ./configure --pr ...

  6. windows下遍历文件夹

    Github地址 函数: HANDLE WINAPI FindFirstFile( _In_ LPCTSTR lpFileName, _Out_ LPWIN32_FIND_DATA lpFindFil ...

  7. AWS访问慢的原因分析及解决方案

    中国区的用户在访问海外AWS服务器的时候会遇到访问很慢的情况,那如何快速访问海外AWS服务器,今天和大家一起聊一下这个话题. 首先,为什么中国的用户访问海外AWS会变慢? 我总结来下大概有以下几方面的 ...

  8. 初学dp心得

    从STL到贪心,再到现在的动态规划,可以说动态规划真的让我学的有点蒙,对于一些题目,会做,但是不会用DP,现在还不能熟练的写出状态转移方程,更重要的是,自己宛如一个哺乳期的小孩,做题需要套模板,没有模 ...

  9. CodeForces 1058C C. Vasya and Golden Ticket

    C. Vasya and Golden Ticket time limit per test1 second memory limit per test256 megabytes inputstand ...

  10. The 2019 Asia Nanchang First Round Online Programming Contest B Fire-Fighting Hero(阅读理解)

    This is an era of team success, but also an era of heroes. Throughout the ages, there have been nume ...