当前位置:首页 > 文章列表 > Golang > Go教程 > GoFrame gmap遍历hashmap listmap treemap使用技巧

GoFrame gmap遍历hashmap listmap treemap使用技巧

来源:脚本之家 2022-12-30 07:41:12 0浏览 收藏

知识点掌握了,还需要不断练习才能熟练运用。下面golang学习网给大家带来一个Golang开发实战,手把手教大家学习《GoFrame gmap遍历hashmap listmap treemap使用技巧》,在实现功能的过程中也带大家重新温习相关知识点,温故而知新,回头看看说不定又有不一样的感悟!

文章比较硬核,爆肝2千多字,除了hashmap、listmap、treemap使用技巧阅读还有使用gmap的踩坑之旅,阅读大约需要5~10分钟。

先说结论

map类型

一图胜千言:

实例化示例:

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

使用技巧

当我们对返回顺序有要求时不能使用hashmap,因为hashmap返回的是无序列表;

当需要按输入顺序返回结果时使用listmap;

当需要让返回结果自然升序排列时使用treemap

package main
import (
   "fmt"
   "github.com/gogf/gf/container/gmap"
   "github.com/gogf/gf/frame/g"
   "github.com/gogf/gf/util/gutil"
)
func main() {
   array := g.Slice{5, 1, 2, 7, 3, 9, 0}
   hashMap := gmap.New(true)
   listMap := gmap.NewListMap(true)
   treeMap := gmap.NewTreeMap(gutil.ComparatorInt, true)
   // 赋值
   for _, v := range array {
      hashMap.Set(v, v)
      listMap.Set(v, v)
      treeMap.Set(v, v)
   }
   //打印结果
   fmt.Println("hashMap.Keys()  :", hashMap.Keys())
   fmt.Println("hashMap.Values():", hashMap.Values())
   //从打印结果可知hashmap的键列表和值列表返回值的顺序没有规律,随机返回
   fmt.Println("listMap.Keys()  :", listMap.Keys())
   fmt.Println("listMap.Values():", listMap.Values())
   //listmap键列表和值列表有序返回,且顺序和写入顺序一致
   fmt.Println("treeMap.Keys()  :", treeMap.Keys())
   fmt.Println("treeMap.Values():", treeMap.Values())
   //treemap键列表和值列表也有序返回,但是不和写入顺序一致,按自然数升序返回
}

打印结果

hashMap.Keys()  : [5 1 2 7 3 9 0]
hashMap.Values(): [2 7 3 9 0 5 1]
listMap.Keys()  : [5 1 2 7 3 9 0]
listMap.Values(): [5 1 2 7 3 9 0]
treeMap.Keys()  : [0 1 2 3 5 7 9]
treeMap.Values(): [0 1 2 3 5 7 9]

为了让大家更好的理解gmap,下面介绍一下gmap的基础使用和一些进阶技巧。

基础概念

GoFrame框架(下文简称gf)提供的数据类型,比如:字典gmap、数组garray、集合gset、队列gqueue、树形结构gtree、链表glist都是支持设置并发安全开关的。

支持设置并发安全开关这也是gf提供的常用数据类型和原生数据类型非常重要的区别

今天和大家分享gf框架中gmap相关知识点

对比sync.Map

go语言提供的原生map不是并发安全的map类型

go语言从1.9版本开始引入了并发安全的sync.Map,但gmap比较于标准库的sync.Map性能更加优异,并且功能更加丰富。

基础使用

  • gmap.New(true) 在初始化的时候开启并发安全开关
  • 通过 Set() 方法赋值,通过 Sets() 方法批量赋值
  • 通过 Size() 方法获取map大小
  • 通过 Get() 根据key获取value值
  • ...

为了方便大家更好的查看效果,在下方代码段中标明了打印结果

package main
import (
   "fmt"
   "github.com/gogf/gf/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/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 基础使用和自定义遍历 介绍的,gf框架提供的数据类型不仅支持设置并发安全,也都支持序列化和反序列化。

json序列化和反序列化:序列化就是转成json格式,反序列化就是json转成其他格式类型(比如:map、数组、对象等)

package main
import (
   "encoding/json"
   "fmt"
   "github.com/gogf/gf/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("序列化结果:", res) //打印结果:{"age":28,"name":"王中阳"}
   // 反序列化
   m2 := gmap.New()
   s := []byte(`{"age":28,"name":"王中阳"}`)
   _ = json.Unmarshal(s, &m2)
   fmt.Println("反序列化结果:", m2.Map()) //反序列化结果: map[age:28 name:王中阳]
}

踩坑

正如上面代码段中注释提到的:

在进行序列化操作时,必须实例化map

m := gmap.New() 

只是声明map而不进行实例化,是无法序列化成功的

var m gmap.Map

过滤空值

package main
import (
   "fmt"
   "github.com/gogf/gf/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,其他都返回
   // 打印结果和预期的一致:
   //m1.FilterEmpty(): {"k5":1}
   //m2.FilterNil(): {"k1":"","k3":0,"k4":false,"k5":1}
}

打印结果

m1.FilterEmpty(): {"k5":1}
m2.FilterNil(): {"k1":"","k3":0,"k4":false,"k5":1}

键值对反转 Flip

package main
import (
   "github.com/gogf/gf/container/gmap"
   "github.com/gogf/gf/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())
}

打印结果

反转前:{
       "k1": "v1",
       "k2": "v2"
}
反转后:{
       "v1": "k1",
       "v2": "k2"
}   

出栈(随机出栈)

package main
import (
   "fmt"
   "github.com/gogf/gf/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()) //多次测试之后发现也是随机出栈
}

运行结果

踩坑

注意:多次测试后发现是随机出栈,不能理所当然的认为按顺序出栈

总结

通过这篇文章,我们了解到:

重点消化一下map遍历时,不同map的特点:

  • 1.1 当我们对返回顺序有要求时不能使用hashmap,因为hashmap返回的是无序列表;
  • 1.2 当需要按输入顺序返回结果时使用listmap;
  • 1.3 当需要让返回结果自然升序排列时使用treemap

gmap的基础使用和进阶使用技巧:反转map、序列化、合并map、出栈等。

gf框架提供的数据结构,比如:字典gmap、数组garray、集合gset、队列gqueue、树形结构gtree、链表glist 都是支持设置并发安全开关的;而且都支持序列化和反序列化,实现了标准库json数据格式的序列化/反序列化接口。

今天关于《GoFrame gmap遍历hashmap listmap treemap使用技巧》的内容就介绍到这里了,是不是学起来一目了然!想要了解更多关于golang的内容请关注golang学习网公众号!

版本声明
本文转载于:脚本之家 如有侵犯,请联系study_golang@163.com删除
GoFrame框架garray对比PHP的array优势GoFrame框架garray对比PHP的array优势
上一篇
GoFrame框架garray对比PHP的array优势
GoFrame框架使用避坑指南和实践干货
下一篇
GoFrame框架使用避坑指南和实践干货
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    542次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    508次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    497次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    484次学习
查看更多
AI推荐
  • 笔灵AI生成答辩PPT:高效制作学术与职场PPT的利器
    笔灵AI生成答辩PPT
    探索笔灵AI生成答辩PPT的强大功能,快速制作高质量答辩PPT。精准内容提取、多样模板匹配、数据可视化、配套自述稿生成,让您的学术和职场展示更加专业与高效。
    15次使用
  • 知网AIGC检测服务系统:精准识别学术文本中的AI生成内容
    知网AIGC检测服务系统
    知网AIGC检测服务系统,专注于检测学术文本中的疑似AI生成内容。依托知网海量高质量文献资源,结合先进的“知识增强AIGC检测技术”,系统能够从语言模式和语义逻辑两方面精准识别AI生成内容,适用于学术研究、教育和企业领域,确保文本的真实性和原创性。
    24次使用
  • AIGC检测服务:AIbiye助力确保论文原创性
    AIGC检测-Aibiye
    AIbiye官网推出的AIGC检测服务,专注于检测ChatGPT、Gemini、Claude等AIGC工具生成的文本,帮助用户确保论文的原创性和学术规范。支持txt和doc(x)格式,检测范围为论文正文,提供高准确性和便捷的用户体验。
    30次使用
  • 易笔AI论文平台:快速生成高质量学术论文的利器
    易笔AI论文
    易笔AI论文平台提供自动写作、格式校对、查重检测等功能,支持多种学术领域的论文生成。价格优惠,界面友好,操作简便,适用于学术研究者、学生及论文辅导机构。
    40次使用
  • 笔启AI论文写作平台:多类型论文生成与多语言支持
    笔启AI论文写作平台
    笔启AI论文写作平台提供多类型论文生成服务,支持多语言写作,满足学术研究者、学生和职场人士的需求。平台采用AI 4.0版本,确保论文质量和原创性,并提供查重保障和隐私保护。
    35次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议隐私政策
返回登录
  • 重置密码