XMap Guide - zhoudm1743/go-util GitHub Wiki
XMap 是 Go-Util 的核心映射处理工具,基于 Go 泛型设计,提供类型安全的映射操作,让键值对数据处理变得简单而高效。
- 🧩 泛型支持: 完整的类型安全,编译时错误检查
- 🔗 链式调用: 流畅的方法链,提高代码可读性
- ⚡ 高性能: 优化的数据结构和算法实现
- 🔄 函数式编程: Map、Filter、Reduce 等高阶函数
- 📊 丰富功能: 涵盖所有常见映射操作场景
- 🔧 易扩展: 支持自定义比较和转换函数
import util "github.com/zhoudm1743/go-util"
// 创建空映射
m := util.NewMap[string, int]()
// 从现有map创建
existing := map[string]int{"a": 1, "b": 2, "c": 3}
m2 := util.MapFromNative(existing)
// 预分配容量的映射
largeMap := util.NewMapWithCapacity[string, int](1000)
// 快速创建
m3 := util.QuickMap(map[string]int{
"apple": 1,
"banana": 2,
"cherry": 3,
})
// 从键值对创建
m4 := util.MapFromPairs([]util.Pair[string, int]{
{"x", 10},
{"y", 20},
{"z", 30},
})
m := util.QuickMap(map[string]int{
"apple": 1, "banana": 2, "cherry": 3,
})
// 大小和状态
fmt.Println(m.Size()) // 3
fmt.Println(m.Len()) // 3 (别名)
fmt.Println(m.IsEmpty()) // false
fmt.Println(m.IsNotEmpty()) // true
// 转换为原生map
nativeMap := m.ToMap() // map[string]int
fmt.Println(nativeMap)
// 获取所有键和值
keys := m.Keys() // []string{"apple", "banana", "cherry"}
values := m.Values() // []int{1, 2, 3}
m := util.NewMap[string, int]()
// 设置值
m.Set("apple", 1)
m.Set("banana", 2)
// 批量设置
m.SetBatch(map[string]int{
"cherry": 3,
"date": 4,
})
// 链式设置
result := m.Set("apple", 1).
Set("banana", 2).
Set("cherry", 3)
// 获取值
value := m.Get("apple") // 1
value, exists := m.SafeGet("grape") // 0, false
// 带默认值的获取
value = m.GetOr("grape", 999) // 999
// 获取并设置默认值
value = m.GetOrSet("grape", 5) // 5 (并设置到map中)
m := util.QuickMap(map[string]int{
"apple": 1, "banana": 2, "cherry": 3,
})
// 检查键是否存在
exists := m.Has("apple") // true
exists = m.HasKey("grape") // false (别名)
// 检查值是否存在
hasValue := m.HasValue(2) // true
// 删除操作
m.Delete("apple") // 删除单个键
m.Remove("banana") // 删除单个键 (别名)
// 批量删除
m.DeleteKeys("cherry", "date")
// 按条件删除
m.DeleteIf(func(k string, v int) bool {
return v > 2 // 删除值大于2的项
})
// 清空映射
m.Clear()
m := util.QuickMap(map[string]int{
"apple": 1, "banana": 2, "cherry": 3,
})
// 转换值
doubled := m.MapValues(func(v int) int {
return v * 2
}) // {"apple": 2, "banana": 4, "cherry": 6}
// 转换键
upperKeys := m.MapKeys(func(k string) string {
return strings.ToUpper(k)
}) // {"APPLE": 1, "BANANA": 2, "CHERRY": 3}
// 同时转换键和值
transformed := m.Map(func(k string, v int) (string, string) {
return strings.ToUpper(k), fmt.Sprintf("value_%d", v)
}) // {"APPLE": "value_1", "BANANA": "value_2", "CHERRY": "value_3"}
// 转换为不同类型
lengths := m.MapValues(func(v int) string {
return strings.Repeat("*", v)
}) // {"apple": "*", "banana": "**", "cherry": "***"}
m := util.QuickMap(map[string]int{
"apple": 1, "banana": 2, "cherry": 3, "date": 4, "elderberry": 5,
})
// 按值过滤
evens := m.FilterByValue(func(v int) bool {
return v%2 == 0
}) // {"banana": 2, "date": 4}
// 按键过滤
longNames := m.FilterByKey(func(k string) bool {
return len(k) > 5
}) // {"banana": 2, "cherry": 3, "elderberry": 5}
// 按键值对过滤
filtered := m.Filter(func(k string, v int) bool {
return len(k) <= 5 && v >= 2
}) // {"date": 4}
// 拒绝过滤 (排除满足条件的)
rejected := m.Reject(func(k string, v int) bool {
return v < 3
}) // {"cherry": 3, "date": 4, "elderberry": 5}
m := util.QuickMap(map[string]int{
"apple": 1, "banana": 2, "cherry": 3,
})
// 值聚合
sum := m.ReduceValues(func(acc, curr int) int {
return acc + curr
}, 0) // 6
// 键值对聚合
concat := m.Reduce(func(acc string, k string, v int) string {
return acc + fmt.Sprintf("%s:%d,", k, v)
}, "") // "apple:1,banana:2,cherry:3,"
// 查找最大值
maxValue := m.ReduceValues(func(acc, curr int) int {
if curr > acc {
return curr
}
return acc
}, 0) // 3
// 计算总长度
totalKeyLength := m.ReduceKeys(func(acc int, k string) int {
return acc + len(k)
}, 0) // 18
m := util.QuickMap(map[string]int{
"apple": 1, "banana": 2, "cherry": 3,
})
// 基础遍历
m.ForEach(func(k string, v int) bool {
fmt.Printf("%s: %d\n", k, v)
return true // 继续遍历
})
// 条件中断
m.ForEach(func(k string, v int) bool {
fmt.Printf("%s: %d\n", k, v)
return k != "banana" // 遇到banana时停止
})
// 只遍历键
m.ForEachKey(func(k string) {
fmt.Printf("Key: %s\n", k)
})
// 只遍历值
m.ForEachValue(func(v int) {
fmt.Printf("Value: %d\n", v)
})
m := util.QuickMap(map[string]int{
"apple": 1, "banana": 2, "cherry": 3, "date": 2,
})
// 查找第一个匹配的键值对
key, value, found := m.Find(func(k string, v int) bool {
return v == 2
}) // "banana" 或 "date", 2, true
// 查找匹配的键
matchedKey, found := m.FindKey(func(k string, v int) bool {
return len(k) > 5
}) // "banana" 或 "cherry", true
// 查找匹配的值
matchedValue, found := m.FindValue(func(k string, v int) bool {
return strings.HasPrefix(k, "c")
}) // 3, true
// 查找所有匹配
allMatches := m.FindAll(func(k string, v int) bool {
return v >= 2
}) // map[string]int{"banana": 2, "cherry": 3, "date": 2}
m := util.QuickMap(map[string]int{
"apple": 1, "banana": 2, "cherry": 3,
})
// 全部满足
allPositive := m.All(func(k string, v int) bool {
return v > 0
}) // true
// 任意满足
anyEven := m.Any(func(k string, v int) bool {
return v%2 == 0
}) // true
// 无任何满足
noneNegative := m.None(func(k string, v int) bool {
return v < 0
}) // true
// 计数
evenCount := m.Count(func(k string, v int) bool {
return v%2 == 0
}) // 1
m1 := util.QuickMap(map[string]int{
"apple": 1, "banana": 2,
})
m2 := util.QuickMap(map[string]int{
"cherry": 3, "banana": 20, // banana会被覆盖
})
// 合并映射 (后者覆盖前者)
merged := m1.Merge(m2) // {"apple": 1, "banana": 20, "cherry": 3}
// 合并多个映射
m3 := util.QuickMap(map[string]int{"date": 4})
multiMerged := m1.MergeMultiple(m2, m3)
// 自定义合并策略
customMerged := m1.MergeWith(m2, func(key string, v1, v2 int) int {
return v1 + v2 // 相加而不是覆盖
}) // {"apple": 1, "banana": 22, "cherry": 3}
// 原地合并
m1.MergeInPlace(m2) // m1 被修改
m1 := util.QuickMap(map[string]int{
"apple": 1, "banana": 2, "cherry": 3,
})
m2 := util.QuickMap(map[string]int{
"banana": 2, "cherry": 30, "date": 4,
})
// 交集 (相同的键)
intersection := m1.Intersect(m2) // {"banana": 2, "cherry": 3}
// 差集 (m1中有但m2中没有的)
difference := m1.Difference(m2) // {"apple": 1}
// 对称差集
symmetricDiff := m1.SymmetricDifference(m2) // {"apple": 1, "date": 4}
// 检查子集
isSubset := util.QuickMap(map[string]int{"apple": 1}).IsSubsetOf(m1) // true
m := util.QuickMap(map[string]int{
"apple": 1, "banana": 2, "cherry": 3,
})
// 转换为键值对数组
pairs := m.ToPairs() // []Pair[string, int]
for _, pair := range pairs {
fmt.Printf("%s: %d\n", pair.Key, pair.Value)
}
// 转换为数组
keys := m.KeysArray() // XArray[string]
values := m.ValuesArray() // XArray[int]
// 转换为JSON
jsonStr, err := m.ToJSON() // {"apple":1,"banana":2,"cherry":3}
// 从JSON创建
newMap, err := util.MapFromJSON[string, int](jsonStr)
// 反转映射 (值作为键,键作为值)
reversed := m.Invert() // {1: "apple", 2: "banana", 3: "cherry"}
// 按值分组
grouped := m.GroupByValue() // map[int][]string{1: ["apple"], 2: ["banana"], 3: ["cherry"]}
// 投影到新的映射
projected := m.Project(func(k string, v int) (int, string) {
return v, strings.ToUpper(k)
}) // {1: "APPLE", 2: "BANANA", 3: "CHERRY"}
m := util.QuickMap(map[string]int{
"zebra": 1, "apple": 3, "banana": 2,
})
// 按键排序
sortedByKey := m.SortByKeys() // 有序映射: apple->3, banana->2, zebra->1
// 按值排序
sortedByValue := m.SortByValues() // 有序映射: zebra->1, banana->2, apple->3
// 自定义排序
customSorted := m.SortWith(func(k1, v1, k2, v2 string, int) bool {
// 先按值排序,值相同时按键排序
if v1 != v2 {
return v1 < v2
}
return k1 < k2
})
// 获取排序后的键值对
sortedPairs := m.ToSortedPairs(func(p1, p2 util.Pair[string, int]) bool {
return p1.Value < p2.Value
})
// 创建有序映射
orderedMap := util.NewOrderedMap[string, int]()
orderedMap.Set("first", 1)
orderedMap.Set("second", 2)
orderedMap.Set("third", 3)
// 按插入顺序遍历
orderedMap.ForEach(func(k string, v int) bool {
fmt.Printf("%s: %d\n", k, v) // 保证顺序
return true
})
// 获取第一个和最后一个
firstKey, firstValue := orderedMap.First()
lastKey, lastValue := orderedMap.Last()
// 深度拷贝
original := util.QuickMap(map[string][]int{
"a": {1, 2, 3},
"b": {4, 5, 6},
})
deepCopy := original.DeepCopy(func(slice []int) []int {
newSlice := make([]int, len(slice))
copy(newSlice, slice)
return newSlice
})
// 深度合并
nested1 := util.QuickMap(map[string]map[string]int{
"user1": {"score": 100, "level": 5},
"user2": {"score": 80},
})
nested2 := util.QuickMap(map[string]map[string]int{
"user1": {"level": 6, "coins": 1000},
"user3": {"score": 90, "level": 3},
})
deepMerged := nested1.DeepMerge(nested2, func(m1, m2 map[string]int) map[string]int {
result := make(map[string]int)
for k, v := range m1 {
result[k] = v
}
for k, v := range m2 {
result[k] = v // 覆盖或添加
}
return result
})
// 创建并发安全的映射
safeMap := util.NewSafeMap[string, int]()
// 并发操作
var wg sync.WaitGroup
for i := 0; i < 100; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
key := fmt.Sprintf("key_%d", id)
safeMap.Set(key, id)
if value, exists := safeMap.SafeGet(key); exists {
fmt.Printf("Got %s: %d\n", key, value)
}
}(i)
}
wg.Wait()
// 原子操作
safeMap.Update("counter", func(oldValue int, exists bool) int {
if exists {
return oldValue + 1
}
return 1
})
// 创建带过期时间的映射
cache := util.NewExpiringMap[string, string](5 * time.Minute)
// 设置带过期时间的值
cache.SetWithTTL("session_123", "user_data", 10*time.Minute)
// 获取值 (自动处理过期)
if value, exists := cache.Get("session_123"); exists {
fmt.Printf("Session data: %s\n", value)
}
// 清理过期项
cache.CleanExpired()
// LRU缓存
lruCache := util.NewLRUMap[string, interface{}](100) // 最大100项
lruCache.Set("recent", "data")
// ✅ 预分配容量
expectedSize := 10000
m := util.NewMapWithCapacity[string, int](expectedSize)
// ✅ 批量操作
data := map[string]int{
"key1": 1, "key2": 2, "key3": 3,
}
m.SetBatch(data)
// ✅ 原地操作
m.FilterInPlace(func(k string, v int) bool {
return v > 0
})
// ❌ 避免频繁的小操作
for i := 0; i < 1000; i++ {
m := util.NewMap[string, int]() // 每次都创建新映射
m.Set(fmt.Sprintf("key_%d", i), i)
}
// 使用对象池
var mapPool = sync.Pool{
New: func() interface{} {
return util.NewMapWithCapacity[string, int](16)
},
}
func ProcessData(data []Item) map[string]int {
m := mapPool.Get().(*util.XMap[string, int])
defer func() {
m.Clear() // 清空后归还
mapPool.Put(m)
}()
// 处理数据
for _, item := range data {
m.Set(item.Key, item.Value)
}
return m.ToMap() // 返回原生map
}
// 配置映射处理
type Config struct {
settings *util.XMap[string, interface{}]
}
func NewConfig() *Config {
return &Config{
settings: util.NewMap[string, interface{}](),
}
}
func (c *Config) LoadFromJSON(jsonStr string) error {
data := make(map[string]interface{})
if err := json.Unmarshal([]byte(jsonStr), &data); err != nil {
return err
}
c.settings = util.MapFromNative(data)
return nil
}
func (c *Config) Get(key string) interface{} {
return c.settings.GetOr(key, nil)
}
func (c *Config) GetString(key string) string {
if value := c.Get(key); value != nil {
if str, ok := value.(string); ok {
return str
}
}
return ""
}
func (c *Config) GetDefaults() *util.XMap[string, interface{}] {
return c.settings.Filter(func(k string, v interface{}) bool {
return strings.HasPrefix(k, "default_")
})
}
// 数据分析和统计
func AnalyzeUserActions(actions []UserAction) *util.XMap[string, ActionStats] {
stats := util.NewMap[string, ActionStats]()
// 按用户分组统计
for _, action := range actions {
stats.Update(action.UserID, func(existing ActionStats, exists bool) ActionStats {
if !exists {
existing = ActionStats{}
}
existing.Count++
existing.LastAction = action.Timestamp
if action.Type == "purchase" {
existing.Revenue += action.Amount
}
return existing
})
}
return stats
}
// 频率统计
func CountFrequency(items []string) *util.XMap[string, int] {
counter := util.NewMap[string, int]()
for _, item := range items {
counter.Update(item, func(count int, exists bool) int {
return count + 1
})
}
return counter
}
// Top K 统计
func TopKItems(counter *util.XMap[string, int], k int) []util.Pair[string, int] {
return counter.
ToPairs().
SortWith(func(p1, p2 util.Pair[string, int]) bool {
return p1.Value > p2.Value // 降序排列
}).
Take(k).
ToSlice()
}
// 会话管理
type SessionManager struct {
sessions *util.SafeMap[string, *Session]
ttl time.Duration
}
func NewSessionManager(ttl time.Duration) *SessionManager {
return &SessionManager{
sessions: util.NewSafeMap[string, *Session](),
ttl: ttl,
}
}
func (sm *SessionManager) CreateSession(userID string) string {
sessionID := generateSessionID()
session := &Session{
ID: sessionID,
UserID: userID,
CreatedAt: time.Now(),
Data: util.NewMap[string, interface{}](),
}
sm.sessions.Set(sessionID, session)
return sessionID
}
func (sm *SessionManager) GetSession(sessionID string) (*Session, bool) {
session, exists := sm.sessions.SafeGet(sessionID)
if !exists {
return nil, false
}
// 检查过期
if time.Since(session.CreatedAt) > sm.ttl {
sm.sessions.Delete(sessionID)
return nil, false
}
return session, true
}
func (sm *SessionManager) CleanExpiredSessions() {
now := time.Now()
expiredSessions := util.NewArray[string]()
sm.sessions.ForEach(func(id string, session *Session) bool {
if now.Sub(session.CreatedAt) > sm.ttl {
expiredSessions.Append(id)
}
return true
})
expiredSessions.ForEach(func(i int, id string) bool {
sm.sessions.Delete(id)
return true
})
}
// HTTP头部处理
func ProcessHeaders(headers map[string][]string) *util.XMap[string, string] {
processed := util.NewMap[string, string]()
headerMap := util.MapFromNative(headers)
return headerMap.MapValues(func(values []string) string {
if len(values) > 0 {
return values[0] // 取第一个值
}
return ""
}).Filter(func(k string, v string) bool {
return v != "" // 过滤空值
})
}
// API响应构建
func BuildAPIResponse(data interface{}, meta map[string]interface{}) map[string]interface{} {
response := util.NewMap[string, interface{}]()
response.Set("data", data)
response.Set("timestamp", time.Now().Unix())
response.Set("status", "success")
if meta != nil {
metaMap := util.MapFromNative(meta)
response.Merge(metaMap)
}
return response.ToMap()
}
操作类型 元素数量 性能指标
基础操作 (Set/Get) 10万 纳秒级
Map 转换 10万 毫秒级
Filter 过滤 10万 毫秒级
Merge 合并 10万 毫秒级
Reduce 聚合 10万 毫秒级
并发操作 (SafeMap) 10万 微秒级
// 基准测试示例
func BenchmarkMapOperations(b *testing.B) {
data := make(map[string]int)
for i := 0; i < 10000; i++ {
data[fmt.Sprintf("key_%d", i)] = i
}
m := util.MapFromNative(data)
b.ResetTimer()
b.ReportAllocs()
for i := 0; i < b.N; i++ {
result := m.
Filter(func(k string, v int) bool { return v%2 == 0 }).
MapValues(func(v int) int { return v * 2 }).
ToMap()
_ = result
}
}
// 结果示例:
// BenchmarkMapOperations-8 500 2.4ms/op 256KB/op 5000 allocs/op
// ✅ 预分配容量
m := util.NewMapWithCapacity[string, int](expectedSize)
// ✅ 使用批量操作
m.SetBatch(largeData)
m.FilterInPlace(condition)
// ✅ 选择合适的数据结构
if needThreadSafe {
m := util.NewSafeMap[string, int]()
} else {
m := util.NewMap[string, int]()
}
// ❌ 避免频繁的小操作
for key, value := range data {
m := util.NewMap[string, int]() // 每次都创建新映射
m.Set(key, value)
}
// ✅ 及时释放大映射
defer func() { largeMap.Clear() }()
// ✅ 使用对象池
m := mapPool.Get().(*util.XMap[string, int])
defer mapPool.Put(m)
// ✅ 选择合适的操作
if needNewMap {
filtered := m.Filter(condition) // 创建新映射
} else {
m.FilterInPlace(condition) // 原地修改
}
// ✅ 使用有意义的链式操作
userStats := rawData.
FilterByKey(isValidUser). // 步骤1:过滤有效用户
MapValues(calculateScore). // 步骤2:计算分数
Filter(func(k string, v int) bool {
return v >= minimumScore // 步骤3:分数筛选
}).
SortByValues() // 步骤4:按分数排序
// ✅ 使用语义化的函数名
isActiveUser := func(k string, v UserInfo) bool {
return v.Status == "active"
}
activeUsers := users.Filter(isActiveUser)
如果您在使用 XMap 时遇到问题:
- 🔍 查看FAQ - 常见映射处理问题
- 🐛 报告问题 - Bug反馈
- 💡 功能建议 - 新功能讨论
- 📧 邮件支持 - [email protected]
🎉 现在您已经掌握了 XMap 的强大功能,开始在项目中使用这些优雅的映射操作吧!