国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

GoFrame的gmap相比Go原生的map,天然支持排序和有序遍歷!?

開發 后端
GoFrame提供的gmap字典類型,包含多個數據結構的map容器:HashMap、TreeMap和ListMap。其中TreeMap支持排序,TreeMap和ListMap支持有序遍歷。

前言

有好多初學GO的小伙伴都被Go語言中map的無序性“坑過”。尤其是PHP轉Go的小伙伴~

這篇文章會為大家介紹:

GoFrame的gmap相比于Go原生的map有什么優勢?為什么天然支持排序和有序遍歷?如何做到的?

GoFrame的gmap有哪些使用技巧?

先說結論

GoFrame提供的gmap字典類型,包含多個數據結構的map?容器:HashMap、TreeMap和ListMap?。其中TreeMap?支持排序,TreeMap和ListMap支持有序遍歷。

使用技巧

我們在使用GoFrame的gmap時,要結合自己的場景使用合適的map容器:

  • 當我們對返回順序有要求時不能使用HashMap?,因為HashMap返回的是無序列表;
  • 當需要按輸入順序返回結果時使用ListMap;
  • 當需要讓返回結果按照自然升序排列時使用TreeMap;

注意:gmap的實例化默認是HashMap?類型:hashMap := gmap.New(true)?

一圖勝千言

GoFrame gmap 基本介紹:

支持并發安全開關選項的map容器,最常用的數據結構。

該模塊包含多個數據結構的map?容器:HashMap、TreeMap和ListMap。

實例化示例:

   hashMap := gmap.New(true)
listMap := gmap.NewListMap(true)
treeMap := gmap.NewTreeMap(gutil.ComparatorInt, true)

實踐得真知

package main

import (
"fmt"
"github.com/gogf/gf/v2/container/gmap"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/util/gutil"
)

func main() {
array := g.Slice{1, 5, 2, 3, 4, 6, 8, 7, 9}
hashMap := gmap.New(true)
listMap := gmap.NewListMap(true)
treeMap := gmap.NewTreeMap(gutil.ComparatorInt, true)
for _, v := range array {
hashMap.Set(v, v)
}
for _, v := range array {
listMap.Set(v, v)
}
for _, v := range array {
treeMap.Set(v, v)
}

fmt.Println("HashMap Keys:", hashMap.Keys()) //HashMap Keys: [7 9 1 5 2 4 6 3 8]
fmt.Println("HashMap Values:", hashMap.Values()) //HashMap Values: [6 7 9 1 5 2 4 3 8]
//從打印結果可知hashmap的鍵列表和值列表返回值的順序沒有規律,隨機返回
fmt.Println("ListMap Keys:", listMap.Keys()) //ListMap Keys: [1 5 2 3 4 6 8 7 9]
fmt.Println("ListMap Values:", listMap.Values()) //ListMap Values: [1 5 2 3 4 6 8 7 9]
//listmap鍵列表和值列表有序返回,且順序和寫入順序一致
fmt.Println("TreeMap Keys:", treeMap.Keys()) //TreeMap Keys: [1 2 3 4 5 6 7 8 9]
fmt.Println("TreeMap Values:", treeMap.Values()) //TreeMap Values: [1 2 3 4 5 6 7 8 9]
//treemap鍵列表和值列表也有序返回,但是不和寫入順序一致,按自然數升序返回
}

打印結果

通過打印結果我們可以發現:

hashmap的鍵列表和值列表返回值的順序沒有規律,隨機返回

listmap鍵列表和值列表有序返回,且順序和寫入順序一致

treemap鍵列表和值列表也有序返回,但是不和寫入順序一致,按自然數升序返回

這也佐證了我開篇提到的使用技巧。

為了讓大家更好的理解gmap,下面介紹一下gmap的基礎使用和一些進階技巧。

基礎概念

GoFrame框架(下文簡稱gf)提供的數據類型,比如:字典gmap、數組garray、集合gset、隊列gqueue、樹形結構gtree、鏈表glist都是支持設置并發安全開關的。

支持設置并發安全開關這也是gf提供的常用數據類型和原生數據類型重要的區別之一。

對比sync.Map

Go語言提供的原生map不是并發安全的map類型

Go語言從1.9版本開始引入了并發安全的sync.Map,但gmap比較于標準庫的sync.Map性能更加優異,并且功能更加豐富。

goos: linux
goarch: amd64
Benchmark_GMapSet-4 10000000 209 ns/op 15 B/op 0 allocs/op
Benchmark_SyncMapSet-4 3000000 451 ns/op 67 B/op 3 allocs/op
Benchmark_GMapGet-4 30000000 66.4 ns/op 0 B/op 0 allocs/op
Benchmark_SyncMapGet-4 30000000 36.0 ns/op 0 B/op 0 allocs/op
Benchmark_GMapRemove-4 10000000 207 ns/op 0 B/op 0 allocs/op
Benchmark_SyncMapRmove-4 30000000 42.4 ns/op 0 B/op 0 allocs/op

對性能測試感興趣的小伙伴可以詳細看下官方文檔的介紹[2],不作為這篇文章的重點。

基礎使用

  • gmap.New(true) 在初始化的時候開啟并發安全開關
  • 通過 Set() 方法賦值,通過 Sets() 方法批量賦值
  • 通過 Size() 方法獲取map大小
  • 通過 Get() 根據key獲取value值
  • ...

更多操作大家可以直接查看下方的代碼示例,也歡迎大家動手實踐

為了方便大家更好的查看效果,在下方代碼段中標明了打印結果:

package main

import (
"fmt"
"github.com/gogf/gf/v2/container/gmap"
)

func main() {
m := gmap.New(true)
// 設置鍵值對
for i := 0; i < 10; i++ {
m.Set(i, i)
}
fmt.Println("查詢map大小:", m.Size())

//批量設置鍵值對
m.Sets(map[interface{}]interface{}{
10: 10,
11: 11,
})

// 目前map的值
fmt.Println("目前map的值:", m)

fmt.Println("查詢是否存在鍵值對:", m.Contains(1))

fmt.Println("根據key獲得value:", m.Get(1))

fmt.Println("刪除數據", m.Remove(1))

//刪除多組數據
fmt.Println("刪除前的map大小:", m.Size())
m.Removes([]interface{}{2, 3})
fmt.Println("刪除后的map大小:", m.Size())

//當前鍵名列表
fmt.Println("鍵名列表:", m.Keys()) //我們發現是無序列表
fmt.Println("鍵值列表:", m.Values()) //我們發現也是無序列表

//查詢鍵名,當鍵值不存在時寫入默認值
fmt.Println(m.GetOrSet(20, 20)) //返回值是20
fmt.Println(m.GetOrSet(20, "二十")) //返回值仍然是20,因為key對應的值存在
m.Remove(20)
fmt.Println(m.GetOrSet(20, "二十")) //返回值是二十,因為key對應的值不存在

// 遍歷map
m.Iterator(func(k interface{}, v interface{}) bool {
fmt.Printf("%v:%v \n", k, v)
return true
})

//自定義寫鎖操作
m.LockFunc(func(m map[interface{}]interface{}) {
m[88] = 88
})

// 自定義讀鎖操作
m.RLockFunc(func(m map[interface{}]interface{}) {
fmt.Println("m[88]:", m[88])
})

// 清空map
m.Clear()

//判斷map是否為空
fmt.Println("m.IsEmpty():", m.IsEmpty())
}

運行結果

上面介紹的基礎使用比較簡單,下面介紹進階使用。

合并 merge

注意:Merge()的參數需要是map的引用類型,也就是參數需要傳map的取址符。

package main

import (
"fmt"
"github.com/gogf/gf/v2/container/gmap"
)

func main() {
var m1, m2 gmap.Map
m1.Set("k1", "v1")
m2.Set("k2", "v2")
m1.Merge(&m2)
fmt.Println("m1.Map()", m1.Map()) //m1.Map() map[k1:v1 k2:v2]
fmt.Println("m2.Map()", m2.Map()) //m2.Map() map[k2:v2]
}

打印結果

序列化

正如之前的文章 GoFrame glist 基礎使用和自定義遍歷[3] 介紹的,gf框架提供的數據類型不僅支持設置并發安全開關,也都支持序列化和反序列化。

json序列化和反序列化:序列化就是轉成json格式,反序列化就是json轉成其他格式類型(比如:map、數組、對象等)

package main

import (
"encoding/json"
"fmt"
"github.com/gogf/gf/v2/container/gmap"
)

func main() {
// 序列化
//var m gmap.Map
m := gmap.New() //必須實例化 只是像上面聲明但是不進行實例化,是無法序列化成功的
m.Sets(map[interface{}]interface{}{
"name": "王中陽",
"age": 28,
})
res, _ := json.Marshal(m)
fmt.Println("序列化結果:", string(res)) //打印結果:{"age":28,"name":"王中陽"}

// 反序列化
m2 := gmap.New()
s := []byte(`{"age":28,"name":"王中陽"}`)
_ = json.Unmarshal(s, &m2)
fmt.Println("反序列化結果:", m2.Map()) //反序列化結果:map[age:28 name:王中陽]
}

打印結果

踩坑

正如上面代碼段中注釋掉的://var m gmap.Map

在進行序列化操作時,必須實例化map

m := gmap.New() 

只是聲明map而不進行實例化,是無法序列化成功的

var m gmap.Map

另外一個需要注意的知識點就是過濾空值了:

過濾空值

首先明確:空值和nil是不一樣的。

nil是未定義;而空值包括空字符串,false、0等

package main

import (
"fmt"
"github.com/gogf/gf/v2/container/gmap"
)

func main() {
//首先明確:空值和nil是不一樣的,nil是未定義;而空值包括空字符串,false、0等
m1 := gmap.NewFrom(map[interface{}]interface{}{
"k1": "",
"k2": nil,
"k3": 0,
"k4": false,
"k5": 1,
})

m2 := gmap.NewFrom(map[interface{}]interface{}{
"k1": "",
"k2": nil,
"k3": 0,
"k4": false,
"k5": 1,
})

m1.FilterEmpty()
m2.FilterNil()

fmt.Println("m1.FilterEmpty():", m1) //預測結果:k5:1
fmt.Println("m2.FilterNil():", m2) //預測結果:除了k2,其他都返回
}

打印結果

還有一個非常好用的特性,鍵值對反轉:

鍵值對反轉 Flip

package main

import (
"github.com/gogf/gf/v2/container/gmap"
"github.com/gogf/gf/v2/frame/g"
)

func main() {
// 鍵值對反轉flip
var m gmap.Map
m.Sets(map[interface{}]interface{}{
"k1": "v1",
"k2": "v2",
})
fmt.Println("反轉前:", m.Map())
m.Flip()
fmt.Println("反轉后:", m.Map())
}

打印結果

出棧

package main

import (
"fmt"
"github.com/gogf/gf/v2/container/gmap"
)

func main() {
//pop pops map出棧(彈棧)
var m gmap.Map
m.Sets(map[interface{}]interface{}{
1: 1,
2: 2,
3: 3,
4: 4,
5: 5,
})

fmt.Println("m.Pop()之前:", m.Map())
key, value := m.Pop()
fmt.Println("key:", key)
fmt.Println("value:", value)
fmt.Println("m.Pop()之后:", m.Map()) //多次測試后發現是隨機出棧,不能理所當然的認為按順序出棧

res := m.Pops(2) //參數是出棧個數
fmt.Println("res:", res)
fmt.Println("m.Pops之后:", m.Map()) //多次測試之后發現也是隨機出棧
}

運行結果

踩坑

注意:多次測試后發現是隨機出棧,不能理所當然的認為按順序出棧。

我們深入思考一下原因:其實很簡單,因為代碼示例中gmap.Map對象的底層實現是hashmap,本身就是無序的,當然不可能按順序出棧了。

總結

好了,我們再來回顧一下這篇文章的重點:

  • 我們在使用GoFrame的gmap時,要結合自己的場景使用合適的map容器:

當我們對返回順序有要求時不能使用HashMap?,因為HashMap返回的是無序列表;

當需要按輸入順序返回結果時使用ListMap;

當需要讓返回結果按照自然升序排列時使用TreeMap;

gmap的實例化默認是HashMap?類型:hashMap := gmap.New(true)

  • gmap的基礎使用和進階使用技巧:反轉map、序列化、合并map、出棧等。
  • gf框架提供的數據結構,比如:字典gmap、數組garray、集合gset、隊列gqueue、樹形結構gtree、鏈表glist都是支持設置并發安全開關的;而且都支持序列化和反序列化,實現了標準庫json數據格式的序列化/反序列化接口。

相關文章

[1]# Go容易搞錯的知識點匯總:Go map如何實現排序 部分: https://juejin.cn/post/7131717990558466062#heading-25

[2]官方文檔的介紹: https://goframe.org/pages/viewpage.action?pageId=30736719

[3]GoFrame glist 基礎使用和自定義遍歷: https://juejin.cn/post/7101515355062796296

本文轉載自微信公眾號「 程序員升級打怪之旅」,作者「王中陽Go」,可以通過以下二維碼關注。

轉載本文請聯系「 程序員升級打怪之旅」公眾號。

責任編輯:武曉燕 來源: 程序員升級打怪之旅
相關推薦

2022-11-02 07:46:31

GoFrameGcache緩存

2024-02-26 00:00:00

Gomapslice

2022-12-28 12:11:57

PHPGo框架

2014-07-15 11:16:17

Go語言

2022-04-06 08:19:13

Go語言切片

2023-11-21 15:46:13

Go內存泄漏

2012-06-15 09:56:40

2022-10-10 11:37:14

Gomap內存

2025-04-21 08:00:56

2025-04-27 08:00:35

2025-04-30 09:02:46

2025-04-14 00:00:04

2025-04-21 00:05:00

2025-04-21 00:00:00

Go 開發Go 語言Go 1.9

2025-04-24 09:01:46

2025-04-27 00:00:01

Go 1.16Go 1.15接口

2025-04-23 08:02:40

2025-04-22 08:02:23

2025-04-18 08:07:12

2025-04-17 08:00:48

點贊
收藏

51CTO技術棧公眾號

а天堂中文最新一区二区三区| 中文字幕在线官网| 麻豆成人免费电影| 日本高清不卡的在线| 亚洲美女尤物影院| 欧美猛男gaygay网站| 黄色毛片在线观看| 精品电影在线观看| 粗大的内捧猛烈进出在线视频| 日本一区二区三区在线不卡 | 免费在线一区二区| 久久久久久久久久久久久久久久久久| 欧美国产在线电影| 日本在线成人| 欧美精品成人在线| 国产成人tv| 久久久亚洲影院| 小嫩嫩12欧美| 欧美精品videosex极品1| 国产精品一区二区精品视频观看| 国产亚洲人成网站在线观看| 欧洲一区二区三区精品| 日韩精品中文在线观看| 亚洲va中文在线播放免费| 亚洲欧美激情四射在线日| 日韩网站中文字幕| 久久精品中文字幕一区| 国产电影一区| 97视频色精品| 久久精品99久久无色码中文字幕| 91社区国产高清| 日韩香蕉视频| 一区二区在线观看网站| 波多野结衣中文字幕一区| 久久久久久久久久久久久国产精品| 国产色婷婷亚洲99精品小说| 看黄的a网站| 亚洲成在人线免费| jyzzz在线观看视频| 欧美va亚洲va香蕉在线| 99久久亚洲国产日韩美女| 97碰在线观看| 一区免费在线| 欧美视频在线第一页| 国产精品国产成人国产三级| 在线视频2区| 亚洲精品在线观| 一区二区三区日韩在线观看| 日本精品一区| 欧美1区免费| 日韩欧美在线电影| 国产精品影视在线| 日韩免费一区二区三区在线播放| 国产黄色大片在线观看| 国产午夜亚洲精品午夜鲁丝片| www欧美激情| 亚洲精品成a人| 国产黄色片在线观看| 亚洲第一页中文字幕| 亚洲欧美综合久久久久久v动漫| 欧美孕妇与黑人孕交| 欧美激情1区| 中文字幕一区二区三区四区五区| 欧美激情一区二区三区| 美丽的姑娘在线观看免费动漫| 亚洲激情在线观看视频免费| 精品国产乱子伦一区二区| 黑人中文字幕一区二区三区| 成人午夜大片免费观看| 在线碰免费视频在线观看| 日韩的一区二区| 岳的好大精品一区二区三区| 鲁片一区二区三区| 亚洲国产精品成人综合| 午夜激情视频在线| 久久夜色撩人精品| 精品二区视频| 久久无码高潮喷水| 丁香天五香天堂综合| 超碰在线首页| 亚洲视频一区在线观看| 九九爱精品视频| 日韩电影免费观看| 欧美成人在线影院| 亚洲国产裸拍裸体视频在线观看乱了中文 | 黄色视屏免费在线观看| 日日狠狠久久偷偷四色综合免费| 久久久神马电影| 久久中文字幕电影| av播放在线| 97精品欧美一区二区三区| 老**午夜毛片一区二区三区| 免费裸体视频网站| 中文字幕不卡在线视频极品| 欧美 日韩 国产一区二区在线视频| 老太脱裤子让老头玩xxxxx| 欧美美女直播网站| 日韩1区2区| 狠狠操精品视频| 亚洲激情视频在线播放| 欧美日韩视频| 国产黄色片大全| 不卡av日日日| 国产精品一区二区不卡| 国产在线69| 91麻豆国产语对白在线观看| 中文字幕中文在线不卡住| 毛片无码国产| 亚洲精品欧洲精品| 69堂亚洲精品首页| 伊人久久大香线| 波多野结衣av在线播放| 久久99国产综合精品女同| 国产suv精品一区二区6| 丝袜美腿av在线| 精品日本一区二区三区| 欧美午夜xxx| 欧美色网址大全| www.大网伊人| 97视频在线播放| 国产欧美一区二区三区在线老狼| 韩日精品一区| 国产91视频一区| 亚洲欧美变态国产另类| 国产精品自拍毛片| 日日av拍夜夜添久久免费| 午夜久久久久久久久久久| 亚洲国模精品私拍| 美国av一区二区| av在线之家电影网站| 青青草原成人网| 91成人看片片| 欧洲一级精品| 国产91一区二区三区| 国产午夜精品福利| 日韩欧美精品免费| 精品99re| 国产九色porny| 亚洲网站视频福利| 成人性生交大片免费| 成人免费在线观看视频| 成人性免费视频| 欧美成在线观看| 日韩一区中文字幕| 色喇叭免费久久综合| 毛片在线免费| 久久国产精品亚洲va麻豆| 欧美一区二区三区婷婷月色| 奇米影视7777精品一区二区| 激情aⅴ欧美一区二区欲海潮| 黄瓜视频免费观看在线观看www| 国产精品三级| ts人妖交友网站| 国产精品人人做人人爽| 色8久久精品久久久久久蜜| 午夜日本精品| 操人在线观看| 久久国产色av免费观看| 国产va免费精品高清在线| 日韩欧美中文字幕在线播放| 久久久久久亚洲精品杨幂换脸| 日本不良网站在线观看| 人妻少妇被粗大爽9797pw| 91av在线免费观看视频| 色噜噜狠狠色综合中国| 老牛嫩草一区二区三区日本 | a级片在线免费观看| 青青青青草视频| 日韩av大片在线| 欧美三级乱人伦电影| 免费观看成人av| 日韩免费在线电影| 丝袜国产免费观看| 精品国产免费人成电影在线观...| 精品乱人伦小说| 久久久亚洲综合| 亚洲色图二区| 大香伊人中文字幕精品| 婷婷五月综合缴情在线视频| 国产999精品视频| 日韩一级片在线观看| 久久九九久久九九| 欧美日韩1区2区3区| 色豆豆成人网| 最近中文字幕mv免费高清在线| 日本精品国语自产拍在线观看| 久久亚洲影音av资源网| 欧美系列日韩一区| 99re这里只有精品首页| 伊人久久大香线蕉精品组织观看| 蜜桃视频www网站在线观看| 丁香视频免费观看| 一区二区三区欧美成人| 国产精品免费久久久久影院| 精品少妇一区二区三区视频免付费| 久久这里都是精品| 国产一区二区三区成人欧美日韩在线观看| 96视频在线观看欧美| www视频在线免费观看| gogo高清免费视频|