Go 语言 map 如何顺序读取?

原文链接: Go 语言 map 如何顺序读取?

Go 语言中的 map 是一种非常强大的数据结构,它允许我们快速地存储和检索键值对。

然而,当我们遍历 map 时,会有一个有趣的现象,那就是输出的键值对顺序是不确定的。

现象

先看一段代码示例:

package main

import "fmt"

func main() {
    m := map[string]int{
        "apple":  1,
        "banana": 2,
        "orange": 3,
    }

    for k, v := range m {
        fmt.Printf("key=%s, value=%d\n", k, v)
    }
}

当我们多执行几次这段代码时,就会发现,输出的顺序是不同的。

原因

首先,Go 语言 map 的底层实现是哈希表,在进行插入时,会对 key 进行 hash 运算。这也就导致了数据不是按顺序存储的,和遍历的顺序也就会不一致。

第二,map 在扩容后,会发生 key 的搬迁,原来落在同一个 bucket 中的 key,搬迁后,有些 key 可能就到其他 bucket 了。

而遍历的过程,就是按顺序遍历 bucket,同时按顺序遍历 bucket 中的 key。

搬迁后,key 的位置发生了重大的变化,有些 key 被搬走了,有些 key 则原地不动。这样,遍历 map 的结果就不可能按原来的顺序了。

最后,也是最有意思的一点。

那如果说我已经初始化好了一个 map,并且不对这个 map 做任何操作,也就是不会发生扩容,那遍历顺序是固定的吗?

答:也不是。

Go 杜绝了这种做法,主要是担心程序员会在开发过程中依赖稳定的遍历顺序,因为这是不对的。

所以在遍历 map 时,并不是固定地从 0 号 bucket 开始遍历,每次都是从一个随机值序号的 bucket 开始遍历,并且是从这个 bucket 的一个随机序号的 cell 开始遍历。

如何顺序读取

如果希望按照特定顺序遍历 map,可以先将键或值存储到切片中,然后对切片进行排序,最后再遍历切片。

改造一下上面的代码,让它按顺序输出:

package main

import (
    "fmt"
    "sort"
)

func main() {
    m := map[string]int{
        "apple":  1,
        "banana": 2,
        "orange": 3,
    }

    // 将 map 中的键存储到切片中
    keys := make([]string, 0, len(m))
    for k := range m {
        keys = append(keys, k)
    }

    // 对切片进行排序
    sort.Strings(keys)

    // 按照排序后的顺序遍历 map
    for _, k := range keys {
        fmt.Printf("key=%s, value=%d\n", k, m[k])
    }
}

在上面的代码中,首先将 map 中的键存储到一个切片中,然后对切片进行排序。

最后,按照排序后的顺序遍历 map。这样就可以按照特定顺序输出键值对了。

以上就是本文的全部内容,如果觉得还不错的话欢迎点赞转发关注,感谢支持。


参考文章:

  • http://go.dev/blog/maps
  • http://golang.design/go-questions/map/unordered/

推荐阅读:

  • Go 语言 map 是并发安全的吗?
  • Go 语言切片是如何扩容的?
  • Go 语言数组和切片的区别
  • Go 语言 new 和 make 关键字的区别
  • 为什么 Go 不支持 []T 转换为 []interface
  • 为什么 Go 语言 struct 要使用 tags
本文转载于网络 如有侵权请联系删除

相关文章

  • 第六届未来网络发展大会志愿者招募启动!一起点亮未来之光!

    如果你想亲自参与一场国际级的网络盛会深度体验未来网络领域的科技变革近距离接触众多顶尖学者、行业大咖那就快来报名参加第六届未来网络发展大会志愿者招募一起点亮未来之光!FNDC大会简介未来网络发展大会于2017年至2021年已成功举办五届,成为全球未来网络领域高规格的盛会,搭建了未来网络领域最前沿的国际化对话平台,共同探讨全球未来网络的合作发展。每届参会嘉宾均超过3000人,一系列“全球首个”创新成果在大会上发布,向世界展现中国未来网络之变,引领全球未来网络行业发展。第六届未来网络发展大会拟于2022年8月24至25日在南京上秦淮国际文化交流中心举办。本届大会将围绕网络操作系统、6G通信、算力网络、工业互联网、网络智能等热点话题,举办高峰论坛、多个主题论坛,以及未来网络领域创新成果发布、未来网络科技创新大赛、创新成果展览等活动。全球未来网络行业领军专家、学者、知名企业家汇聚一堂,共同筹划网络与通信发展,推动未来走进现实。FNDC成为大会志愿者,你可以W  ENEEDYOU近距离接触院士学者、科技大咖聆听最前沿的未来网络行业动态见识最新潮的科技作品、研究成果锻炼提升大型活动现场执行能力获得官

  • Spring Boot第八章-Spring Data JPA(续)

    目录1.jpa自定义sql查询2.jpa更新3.jpa删除4.一些常用注解的理解5.自定义查询简单实例:6.JPA关联表自定义动态查询1.jpa自定义sql查询直接上代码://自定义查询 @Query(value="select*frompersonwherename=?1andage>18",nativeQuery=true) List<Person>findByMyQuery(Stringname);复制此处跟之前的@Query有区别,nativeQuery=true,这样的话就用本地的查询语句了,根据value里面的正常的sql语句进行查询,注意这里写的就是真实的表名了。而如果不是nativeQuery=true,写的是类名。2.jpa更新直接上代码://更新操作(更新,删除的操作必须有事务,这个事务可以在这里写,也可以在service里写) @Transactional @Modifying @Query(value="updatePersonsetage=?2whereid=?1") intupdatePersonAg

  • 在深度卷积神经网络中使用稀疏性和模式进行推理的高性能卷积

    部署深度卷积神经网络(CNNs)受到其内存占用和速度要求的影响,这些要求主要来自卷积。广泛使用的卷积算法im2col和MEC,通过冗余存储地图在水平和/或垂直内核重叠处包含的元素,从激活图产生一个降低的矩阵,而不考虑地图的稀疏性。利用地图的稀疏性,本文提出了两种新的卷积算法,分别称为压缩模式重叠(CPO)和压缩模式集(CPS),这两种算法在保持精度的同时,减少了内存占用,提高了推理速度。CPO可以识别激活图中水平和垂直重叠处的非零元素(NZE)。CPS通过压缩相邻NZE的索引位置,进一步提高了CPO的内存节省。在这两种算法中,激活图中所有零的通道/区域都被跳过。然后,CPO/CPS通过在其稀疏表示上完成的稀疏矩阵-矢量乘法(SpMv)进行卷积。在CPU上进行的实验结果显示,相对于im2col,平均每层时间节省高达63%,压缩比(CR)高达26倍。在某些层中,我们的平均每层CPO/CPS时间节省了28%,CR比MEC的并行实现好9.2倍。对于一个给定的CNN的推理,我们为每个卷积层离线选择CPO或CPS与im2col之间时间最好的卷积算法。我们的算法被选择到56%的非点状卷积层。我们的离

  • 图数据库HugeGraph源码解读 (1) —— 入门介绍

    HugeGraph介绍以下引自官方文档:HugeGraph是一款易用、高效、通用的开源图数据库系统(GraphDatabase,GitHub项目地址),实现了ApacheTinkerPop3框架及完全兼容Gremlin查询语言,具备完善的工具链组件,助力用户轻松构建基于图数据库之上的应用和产品。HugeGraph支持百亿以上的顶点和边快速导入,并提供毫秒级的关联关系查询能力(OLTP),并可与Hadoop、Spark等大数据平台集成以进行离线分析(OLAP)。 HugeGraph典型应用场景包括深度关系探索、关联分析、路径搜索、特征抽取、数据聚类、社区检测、知识图谱等,适用业务领域有如网络安全、电信诈骗、金融风控、广告推荐、社交网络和智能机器人等。复制划重点: -基于TinkerPop3框架,兼容Gremlin查询语言 -OLTP(开源)与OLAP(商业版) -常用图应用支持——路径搜索、推荐等架构介绍架构图HugeGraph包括三个层次的功能,分别是存储层、计算层和用户接口层。HugeGraph支持OLTP和OLAP两种图计算类型组件HugeGraph的主要功能分为HugeCore

  • 多数据库联合分析肾透明细胞癌免疫浸润轻松发3分+

    今天和大家分享的是2020年3月发表在JournalofCancer(IF:3.182)上的一篇文章,“TheimmuneinfiltrationinclearcellRenalCellCarcinomaandtheirclinicalimplications:AstudybasedonTCGAandGEOdatabases”,作者使用GEO和TCGA数据集研究了肾透明细胞癌中免疫浸润细胞的情况,并与正常组织进行了对比,通过生存分析研究了其临床意义。 标题:TheimmuneinfiltrationinclearcellRenalCellCarcinomaandtheirclinicalimplications:AstudybasedonTCGAandGEOdatabases肾透明细胞癌的免疫浸润及其临床意义:一项基于TCGA和GEO数据库的研究一、研究背景肿瘤微环境由肿瘤细胞、各种免疫浸润细胞、成纤维细胞、许多细胞因子和催化因子组成,是一个动态平衡的复杂系统。免疫应答在肿瘤生长、侵袭和转移中起重要作用,因此肿瘤浸润免疫细胞(TIICs)可以成为化疗放射治疗的靶点。本篇文章中,作者用

  • html网页开发基础

    简介INTRODUCTION讲述html代码结构和基本使用,查看更多...一、html具体是什么? hypertextmarklanguage超文本标记语言使用什么标签呢?<html></html>标签特点是什么?1.成对出现2.用尖括号特殊的情况举例:1.换行<br><br></br><br/>2.线<hr><hr/>等等其它还有一些标签也是单个结束的。二、html的代码结构是怎样的?网页基本代码结构:<html><head></head><body></body></html>head和body之间的区别?head标签:1.可以写网页名称(显示在浏览器的左上方),网页名称用标记<title></title>2.可以写css,使用标记<style></style>3.可以写js(javascript一种脚本语言),使用<script>标记4.可以导入链接<

  • Flutter开发中的一些Tips

    原文作者:唯鹿 https://juejin.im/post/5d00fbfd51882570ec017660学习Flutter也有一阵子了。闲着没事,用了公司一个已经凉凉的App设计图来练手。当然了接口不可能用的了,所以都是些死数据,实现效果可以说是很完美了(得到了设计的认可。。。)。当然自己也是边查边写,也借鉴了许多Github上优秀的Flutter项目。现在开源出来(附带设计图),供大家交流学习。希望多多Star、Fork支持,有问题可以Issue。附上链接:github.com/simplezhli/…本篇主要分享一下自己在此项目中遇到的问题及心得,希望对你有所帮助!1.部件溢出异常大致如下:ARenderFlexoverflowedby22pixelsonthebottom.复制导致的原因就是在水平或者垂直方向上的内容超过了父部件的大小。一般来说我们的页面不存在这样的问题,因为根据页面的设计,事先可以预料到是否超出。不过要注意到有输入法弹出的页面。比如我下面的这个例子:可以看到底部溢出了22个像素,可能在18:9的手机以上不太会出现这种问题,因为屏幕的高度足够。但是这种16:

  • 腾讯云服务器web环境配置教程

    腾讯云服务器是现在越来越多站长以及企业建站的首选了,因为腾讯云背靠腾讯这颗大树,有10亿微信用户和10亿QQ用户流量考验验做为背书,有足够的技术实力和奖金实力让人相信它是靠谱的。双10亿的用户流量都能把持得住,还在乎你个小网站的流量压力吗?对于刚入门的站长,在接触云服务器还不太久,对于云服务器的环境配置还不太熟悉,这里就带大家从购买腾讯云服务器开始,到成功配置好web服务器环境,一步步教你轻松做站长:首先,我们需要购买腾讯云服务器,不是土豪的话可以先点击领取腾讯云代金券再购买推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。https://cloud.tencent.com/redirect.php?redirect=1025&cps_key=6f5f5aedea72d213ca302d15938d0f44&from=console,为你省掉一大笔;热卖云产品3折起,云服务器、云数据库特惠,服务更稳,速度更快,价格更优https://cloud.tencent.com/redirect.php?redirect=1014&am

  • 惊了!百度官方居然推出了免费不限速的网盘下载工具?!

    SVIP们有一句mmp不知道当不当讲。百度网盘是大家十分熟悉的一款产品,曾经功能、速度都还算良心,一度十分火爆。后来,经历了8秒教育片和几次限速之后,大家虽然迫不得已还在用,但是怨声载道。不甘心的技术宅们自然不愿掏钱买会员,去享受原本免费的服务,于是出现了各种魔改客户端,或者油猴脚本,配合别的下载器绕过限制或是多线程加速下载。然而官方经常封杀这些手段,导致这些办法也都是游击战性质,都不是长久之计。不过今天我发现爱奇艺(其实就是百度)悄摸摸地推出了一款名为「爱奇艺万能播放器」的软件,其内置的下载功能居然不受网盘限速,于是来分享给大家。(据说这功能几个月前就有了,只是不普及,话说回来,说不定普及以后就很快又会被限速……)我们随便找一个文件来对网盘客户的和爱奇艺万能播放器作对比。播放器下载地址:https://store.iqiyi.com/web/iqiyi/detail/qisuyingyin.action号称纯净安装。而且我的确没发现有什么捆绑…不符合百度的一贯尿性啊。播放器体积很小,只有17M,安装时注意一下格式关联和路径就好。播放器具体好不好用我还没测试…所以暂时先不关联媒体文件了

  • React native开发中常见的错误

    reactnative环境搭建请移步:reactnative环境搭建这里说说reactnative创建完成之后,运行中出现的常见问题,问题1:java.lang.RuntimeException:SDKlocationnotfound.Definelocationwithsdk.dirinthelocal.propertiesfileorwithanANDROID_HOMEenvironmentvariable.这个是原因是工程找不到我们的androidSDK。解决方法:在工程的根目录下的android文件下新建一个local.properties的文件(我们可以直接拷贝Android项目的local.properties的文件)。问题2:Aproblemoccurredconfiguringproject':app'.>failedtofindBuildToolsrevision23.0.1这个是因为BuildToolsrevision23.0.1和我们的sdk里面的版本不一致导致的。解决方法:这里注意build.gradle和gradle中gradle-w

  • Java学习笔记

    本文主要记录了自己Java学习过程中的笔记,里面有很多Map、List、Set底层的源码解读,且知识点很全面,囊括从基本语法到IO编程、网络编程、并发编程以及反射等相关基础知识。此外,由于图片文件在本地,可能导致一些图片无法再网络上正常加载,造成阅读不便,请谅解。之后的博文都会将图片上传到自己的oos中,故只有本篇图片加载会出现问题,在此说明? 编码 ASCII:用八位二进制的低七位,一共规定了128个字符的编码,一个字节表示一个字符, 扩展ASCII:第八位为1,规定了以1开头的128个字符 Unicode:固定大小的编码,通常两个字节表示一个字符,字母和汉字统一用两个字节,浪费空间 UTF-8:是一种变长的编码方式。字母用一个字节,汉字用三个字节,是在互联网上使用最广的一中Unicode的实现方式 gbk:可以表示汉字,范围广,字母用一个字节,汉字用两个字节ANSI编码--不同地区采用的编码的统称 UTF-8编码规则: 1)对于单字节的符号,字节的第一位设为0,后面7位为这个符号的Unicode码。因此对于英语字母,UTF-8编码和ASCII码是相同的。 2)对于n字节的符号(n&

  • 数据库优化之程序操作优化

     一、操作符优化   1. IN、NOT IN 操作符   IN和EXISTS 性能有外表和内表区分的,但是在大数据量的表中推荐用EXISTS 代替IN 。   Not IN 不走索引的是绝对不能用的,可以用NOT EXISTS 代替   2. IS NULL 或IS NOT NULL操作    索引是不索引空值的,所以这样的操作不能使用索引,可以用其他的办法处理,例如:数字类型,判断大于0,字符串类型设置一个默认值,判断是否等于默认值即可   3. <> 操作符(不等于)   不等于操作符是永远不会用到索引的,因此对它的处理只会产生全表扫描。 用其它相同功能的操作运算代替,如 a<>0 改为 a>0 or a<0    a<>’’ 改为&nb

  • 后记:振华中学,毕业快乐 八月长安

    by:八月长安 在写下这篇后记之前,我刚刚和一位小学同学K通完电话。 我和K自从小学毕业就没有再联络过,他这次通过网络找到我,打来电话问候近况。 其实“近况”是很难讲的,信息要从小学毕业之后开始更新,跨度十二年。每件事情 都需要谈及背景,背景里套着更多背景,陌生人之间联系着更多陌生人。现状实在 无从说起,所以就讲起过去。 但发现过去更难讲。因为他不记得了。 最后只能扯闲话。他开始推荐我平时要多喝功夫茶,这时我忽然冒出一句:“是啊, 你奶奶是茶叶世家出身嘛。” 连我自己都有些惊讶。 更别提我的同学了,他斩钉截铁地表示,她奶奶做了一辈子家庭妇女,绝对不可能 出身于什么茶叶世家。 可我记得,那么清晰,就像是昨天发生的事。 小学高年级的夏天,午休时我在学校外面的小超市遇见他。我犯困,想要买一袋速 溶咖啡冲来喝,偏偏店主将咖啡都放在了货架最下面的一排,我蹲在地上找。他从 旁边过来,一不留神就把我像球一样踢了。 平时我坐在第二排,是个假正经讨人厌的小班长;K坐在倒数第二排,每天罚站,不 是因为上课说话就是因为作业忘带了。我们在学校不讲话,偶尔在校外碰见也只是点 个头。 那天不知

  • 简述B2B安全通讯的几个概念:CSR CER PFX

    BizTalk培训/项目开发/技术支持需求欢迎随时联系:Email:cbcye@live.com,手机/微信:18511575973   B2B安全通讯的配置过程中经常会遇到CSR、CER、PFX的概念,以下简述一下这几个概念的定义及作用。 SSL SSL握手过程 当客户端连接到支持TLS协议的服务器要求创建安全连接并列出了受支持的密码组合(加密密码算法和加密哈希函数),握手开始。 服务器从该列表中决定加密和散列函数,并通知客户端。 服务器发回其数字证书,此证书通常包含服务器的名称、受信任的证书颁发机构(CA)和服务器的公钥。 客户端确认其颁发的证书的有效性。 为了生成会话密钥用于安全连接,客户端使用服务器的公钥加密随机生成的密钥,并将其发送到服务器,只有服务器才能使用自己的私钥解密。 利用随机数,双方生成用于加密和解密的对称密钥。这就是TLS协议的握手,握手完毕后的连接是安全的,直到连接(被)关闭。如果上述任何一个步骤失败,TLS握手过程就会失败,并且断开所有的连接。   X.509 X.509是密码学里公钥证书的格式标准。X.509证书里含有公钥、身份信

  • linux中find与rm实现查找并删除文件

    find命令: find.-name'*.log'#查找当前目录下的log文件复制   查找并删除: find.-name'*.log'-mtime+7-typef-print-execrm-rf{}\;复制 (1)“.”表示从当前目录开始递归查找 (2)“-name‘*.log’“根据名称来查找,要查找所有以.log结尾的文件夹或者文件 (3)"-mtime+7" 表示7天内没有修改过 (4)”-typef“查找的类型为文件 (5)“-print”输出查找的文件目录名 (6)最主要的是是-exec了,-exec选项后边跟着一个所要执行的命令,表示将find出来的文件或目录执行该命令。 exec选项后面跟随着所要执行的命令或脚本,然后是一对儿{},一个空格和一个\,最后是一个分号

  • UOJ.311.[UNR#2]积劳成疾(DP)

    UOJ 序列中的每个位置是等价的。直接令\(f[i][j]\)表示,\(i\)个数的序列,最大值不超过\(j\)的所有序列每个长为\(k\)的子区间最大值的乘积的和。 由\(j-1\)转移到\(j\)时,考虑枚举第一个\(j\)出现在哪里。设最左边的\(j\)在\(p\)位置,那么会对左端点在\([\max(1,p-k+1),\\min(p,i-k+1)]\)的每个\(k\)区间造成\(w[j]\)的贡献,也就是\(w[j]^{len}\)。\(p\)左边没出现过\(j\),贡献是\(f[p-1][j-1]\);\(p\)右边还可能出现\(j\),贡献是\(f[i-p][j]\)。 所以有\(f[i][j]=f[i][j-1]+\sum_{p=1}^{i}f[p-1][j-1]*w[j]^{len}*f[i-p][j]\)。 注意初始化的问题,\(f[i][j]\(i<k)\)的初值是\(j^i\),即序列个数。(这样\(i\geqk\)的时候是会考虑序列所有构成的) 复杂度\(O(n^3)\)。 //1447ms 2052kb #include<cstdio>

  • 自己用的博客园主题分享(博客园美化diy)

    本博客主题分享,算不上特别好看吧,但是比博客园原来的好看一些,我自己觉得!不接受反驳   选择主题为:(然后保存)            页面定制css代码  /*溢出隐藏设置*/ #topics,#mainContent{ overflow:visible; } #postDesc{ float:none; } #gotop-fixed.calli{ display:inline-block!important; line-height:20px!important; } #gotop-fixed.call{ background-color:#457CE6!important; } #gotop-fixed.goTop{ background-color:#457CE6!important; opacity:0.8; } @mediascreenand(max-width:500px){ body{ color:red; } #page_begin_htmla{ display:no

  • 自动发邮件

    #!/usr/bin/envpython #-*-coding:utf-8-*- #@Project:pythonProject #File:sendmail.py #@Time:2022/4/222:40 #@Author:lilu """ 1,导包 2,建立连接 3、身份认证 4.发送邮件 5、邮件内容:发送人,接收人,主题,内容 """ importsmtplib fromemail.mime.multipartimportMIMEMultipart#发送邮件 fromemail.mime.textimportMIMEText#邮件内容 fromemail.mime.imageimportMIMEImage#发送图片 fromtest_api.common.readconfimportreadconf fromemail.headerimportHeader fromtest_api.common.logimport* defsendmail(): #设置smtplib所需要的参数 #服务器地址 email_info=readconf('email_info') smtp

  • FusionInsight硬件部署指南

    1.硬盘分区原则 当集群节点规模较大时(如大于30节点),管理节点的IO负载可能较高,管理节点的元数据建议采用分盘的模式。 若磁盘容量不满足600GB磁盘规格时,在准备操作系统时请参考《FusionInsightHD软件安装》中“磁盘容量不足如何配置磁盘分区”进行配置。 当元数据分区部署在多块磁盘时,要优先为Zookeeper的数据目录独立分配一块磁盘存放Zookeeper数据,或者分配SSD进行存储。 2.为消除硬盘盘符漂移带来的影响,使用“UUID”或“by-id”进行分区挂载,不能使用逻辑盘符(例如/dev/sda2)进行分区挂载,如“UUID”为例所示。 2.1.查看UUID命令blkid      2.2.查看已挂在的磁盘,输入UUID对应的磁盘文件 2.3.管理元数据分盘(管理节点MN&DNRIAD1)  2.4.Hadoop数据节点RAIDD0或者是no-RAID 2.5.Kafka数据节点RAID5 2.6.Strom数据节点(管理元数据盘RAID1,数据盘RAID0/non-RIAD) 2.7.Solr数据节

  • JS常用屏蔽代码

    转载自WEB开发笔记 www.chhua.com   作为备份和参考:   <bodyoncontextmenu=”returnfalse”></body> <!–禁用右键:–><script>functionstop(){returnfalse;}document.oncontextmenu=stop;</script> <bodyonselectstart=”returnfalse”>取消选取、防止复制 oncopy=”returnfalse;”oncut=”returnfalse;”防止复制 四:禁止查看源文件 <html><head><script>functionclear(){Source=document.body.firstChild.data;document.open();document.close();document.title=”看不到源代码”;document.body.innerHTML=Source;}</sc

  • Linux 环境下安装Redis

    源码安装Redis它来了它来了 我安装的是redis-5.0.5的版本需要其他版本的:http://download.redis.io/releases/ 安装开始: 1.下载压缩包 wgethttp://download.redis.io/releases/redis-5.0.5.tar.gz     2.解压 建议先创建一个redis的文件夹,原因之一方便以后卸载 mkdirredis cdredis      tar-zxvfredis-5.0.5.tar.gz     解压(注意路径) 3.安装gcc环境 redis是由C语言编写的,它的运行需要C环境,所以编译前需安装gcc yuminstallgcc-c++-y     4.编译 进入解压后的redis-5.0.5目录 cdredis-5.0.5 make   出现下面的代码提示,可以看看到大佬说的:    官网里到这一步就结束了,可能新版本

相关推荐

推荐阅读