網站首頁 編程語言 正文
一、為什么是無序的?
開門見山,先上源碼
func mapiterinit(t *maptype, h *hmap, it *hiter) { // decide where to start r := uintptr(fastrand()) if h.B > 31-bucketCntBits { r += uintptr(fastrand()) << 31 } mapiternext(it) }
Go 當我們在遍歷 map 時,并不是固定地從第一個數開始遍歷,每次都是從一個位置開始遍歷。即使是一個不會改變的的 map,僅僅只是遍歷它,也不太可能會返回一個固定順序了。
也就是說,GO語言從語言上進行 Map 的無序。
二、GO 為什么要這么做?
其實主要是因為 map 在擴容后,可能會將部分 key 移至新內存,那么這一部分實際上就已經是無序的了。而遍歷的過程,其實就是按順序遍歷內存地址,同時按順序遍歷內存地址中的 key。但這時已經是無序的了。
當然有人會說,如果我就一個 map,我保證不會對 map 進行修改刪除等操作,那么按理說沒有擴容就不會發生改變。但也是因為這樣,GO 才在源碼中
加上隨機的元素,將遍歷 map 的順序隨機化,用來防止使用者用來順序遍歷。而這是有風險的代碼,在GO 的嚴格語法規則下,是堅決不提倡的。
三、遍歷是否真的無序的
1.第一次遍歷
代碼如下(示例):
package main import "fmt" func main() { noSortMap := map[int]int{ 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, } for k, v := range noSortMap { fmt.Println("key: ", k, "value: ", v) } }
結果果然不出所料,并沒有從第一個數開始
2.第二次遍歷
代碼同上:
結果果然不出所料,與第一次都不相同
四、如何才能得到有序的鍵值對
我們需要使用 切片(Slice) 來進行控制,
1.詳細代碼
代碼如下(示例):
package main import ( "fmt" "sort" ) func main() { noSortMap := map[int]int{ 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, } var noSortSlice []int for k, v := range noSortMap { noSortSlice = append(noSortSlice, k) fmt.Println("key: ", k, "value: ", v) } fmt.Println(noSortSlice) // 排序 sort.Ints(noSortSlice) sortSlice := noSortSlice fmt.Println(sortSlice) for _, k := range sortSlice { fmt.Println("key: ", k, "value: ", noSortMap[k]) } }
先將無序的key 放進切片中
再將無序的切片 調用 sort包的 Ints 方法排序
排序后再遍歷切片,此時切片有序,則 map 的鍵值對也是有序的
總結
不要依賴map遍歷時返回的key順序,采用隨機選擇遍歷起始位置的方式使得遍歷時返回是亂序的。如果想得到有序鍵值,請依靠有序切片進行訪問來得到有效的有序 Map
原文鏈接:https://blog.csdn.net/moer0/article/details/122953493
相關推薦
- 2022-07-07 go語言心跳超時的實現示例_Golang
- 2023-05-15 GoLang中的加密方法小結_Golang
- 2022-06-26 ASP.NET?Core中引用OpenAPI服務的添加示例_實用技巧
- 2022-02-03 Gogs clone倉庫地址為localhost
- 2022-08-28 SpringBoot 實現自定義的 starter
- 2022-07-07 WCF的異常處理_C#教程
- 2022-08-28 linux--network和NetManager沖突導致network[44649]:RTNETL
- 2022-11-23 Python實現定時任務利器之apscheduler使用詳解_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支