- Created by 黄骞, last modified by 郭强 on Nov 19, 2021
并发安全
gmap
支持并发安全选项开关,在默认情况下是非并发安全
的,开发者可以选择开启gmap
的并发安全特性(传递初始化开关参数safe
参数值为true
, 必须在初始化时设定,不能运行时动态设定)。如:
m := gmap.New(true)
不仅仅是gmap
模块,goframe
框架的其他并发安全数据结构也支持并发安全特性开关。
使用示例
基本使用
package main import ( "fmt" "github.com/gogf/gf/v2/container/gmap" ) func main() { // 创建一个默认的gmap对象, // 默认情况下该gmap对象不支持并发安全特性, // 初始化时可以给定true参数开启并发安全特性。 m := gmap.New() // 设置键值对 for i := 0; i < 10; i++ { m.Set(i, i) } // 查询大小 fmt.Println(m.Size()) // 批量设置键值对(不同的数据类型对象参数不同) m.Sets(map[interface{}]interface{}{ 10 : 10, 11 : 11, }) fmt.Println(m.Size()) // 查询是否存在 fmt.Println(m.Contains(1)) // 查询键值 fmt.Println(m.Get(1)) // 删除数据项 m.Remove(9) fmt.Println(m.Size()) // 批量删除 m.Removes([]interface{}{10, 11}) fmt.Println(m.Size()) // 当前键名列表(随机排序) fmt.Println(m.Keys()) // 当前键值列表(随机排序) fmt.Println(m.Values()) // 查询键名,当键值不存在时,写入给定的默认值 fmt.Println(m.GetOrSet(100, 100)) // 删除键值对,并返回对应的键值 fmt.Println(m.Remove(100)) // 遍历map m.Iterator(func(k interface{}, v interface{}) bool { fmt.Printf("%v:%v ", k, v) return true }) // 自定义写锁操作 m.LockFunc(func(m map[interface{}]interface{}) { m[99] = 99 }) // 自定义读锁操作 m.RLockFunc(func(m map[interface{}]interface{}) { fmt.Println(m[99]) }) // 清空map m.Clear() // 判断map是否为空 fmt.Println(m.IsEmpty()) }
执行后,输出结果为:
10 12 true 1 11 9 [0 1 2 4 6 7 3 5 8] [3 5 8 0 1 2 4 6 7] 100 100 3:3 5:5 8:8 7:7 0:0 1:1 2:2 4:4 6:6 99 true
有序遍历
我们来看一下三种不同类型map
的有序性遍历示例。
package main import ( "fmt" "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/container/gmap" "github.com/gogf/gf/v2/util/gutil" ) func main() { array := g.Slice{2, 3, 1, 5, 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()) fmt.Println("HashMap Values:", hashMap.Values()) fmt.Println("ListMap Keys:", listMap.Keys()) fmt.Println("ListMap Values:", listMap.Values()) fmt.Println("TreeMap Keys:", treeMap.Keys()) fmt.Println("TreeMap Values:", treeMap.Values()) }
执行后,输出结果为:
HashMap Keys: [4 6 8 7 9 2 3 1 5] HashMap Values: [6 8 4 3 1 5 7 9 2] ListMap Keys: [2 3 1 5 4 6 8 7 9] ListMap Values: [2 3 1 5 4 6 8 7 9] TreeMap Keys: [1 2 3 4 5 6 7 8 9] TreeMap Values: [1 2 3 4 5 6 7 8 9]
FilterEmpty/FilterNil
空值过滤
package main import ( "fmt" "github.com/gogf/gf/v2/container/gmap" "github.com/gogf/gf/v2/frame/g" ) func main() { m1 := gmap.NewFrom(g.MapAnyAny{ "k1": "", "k2": nil, "k3": 0, "k4": 1, }) m2 := gmap.NewFrom(g.MapAnyAny{ "k1": "", "k2": nil, "k3": 0, "k4": 1, }) m1.FilterEmpty() m2.FilterNil() fmt.Println(m1.Map()) fmt.Println(m2.Map()) // Output: // map[k4:1] // map[k1: k3:0 k4:1] }
Flip
键值对反转
package main import ( "fmt" "github.com/gogf/gf/v2/container/gmap" "github.com/gogf/gf/v2/frame/g" ) func main() { var m gmap.Map m.Sets(g.MapAnyAny{ "k1": "v1", "k2": "v2", }) m.Flip() fmt.Println(m.Map()) // May Output: // map[v1:k1 v2:k2] }
Keys/Values
键名/数值列表
package main import ( "fmt" "github.com/gogf/gf/v2/container/gmap" "github.com/gogf/gf/v2/frame/g" ) func main() { var m gmap.Map m.Sets(g.MapAnyAny{ "k1": "v1", "k2": "v2", "k3": "v3", "k4": "v4", }) fmt.Println(m.Keys()) fmt.Println(m.Values()) // May Output: // [k1 k2 k3 k4] // [v2 v3 v4 v1] }
Pop/Pops
随机出栈
package main import ( "fmt" "github.com/gogf/gf/v2/container/gmap" "github.com/gogf/gf/v2/frame/g" ) func main() { var m gmap.Map m.Sets(g.MapAnyAny{ "k1": "v1", "k2": "v2", "k3": "v3", "k4": "v4", }) fmt.Println(m.Pop()) fmt.Println(m.Pops(2)) fmt.Println(m.Size()) // May Output: // k1 v1 // map[k2:v2 k4:v4] // 1 }
SetIfNotExist*
判断性写入
判断性写入是指当指定的键名不存在时则写入并且方法返回true
,否则忽略写入并且方法返回false
。相关方法如下:
SetIfNotExist
SetIfNotExistFunc
SetIfNotExistFuncLock
方法具体描述请查看接口文档或源码注释。
package main import ( "fmt" "github.com/gogf/gf/v2/container/gmap" ) func main() { var m gmap.Map fmt.Println(m.SetIfNotExist("k1", "v1")) fmt.Println(m.SetIfNotExist("k1", "v1")) fmt.Println(m.Map()) // Output: // true // false // map[k1:v1] }
Merge
字典表合并
package main import ( "fmt" "github.com/gogf/gf/v2/container/gmap" ) func main() { var m1, m2 gmap.Map m1.Set("key1", "val1") m2.Set("key2", "val2") m1.Merge(&m2) fmt.Println(m1.Map()) // May Output: // map[key1:val1 key2:val2] }
JSON
序列化/反序列
gmap
模块下的所有容器类型均实现了标准库json
数据格式的序列化/反序列化接口。
1. Marshal
package main import ( "encoding/json" "fmt" "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/container/gmap" ) func main() { m := gmap.New() m.Sets(g.MapAnyAny{ "name": "john", "score": 100, }) b, _ := json.Marshal(m) fmt.Println(string(b)) }
执行后,输出结果:
{"name":"john","score":100}
2.Unmarshal
package main import ( "encoding/json" "fmt" "github.com/gogf/gf/v2/container/gmap" ) func main() { m := gmap.Map{} s := []byte(`{"name":"john","score":100}`) json.Unmarshal(s, &m) fmt.Println(m.Map()) }
执行后,输出结果:
map[name:john score:100]
Content Menu
- No labels