XMap Guide - zhoudm1743/go-util GitHub Wiki

XMap 是 Go-Util 的核心映射处理工具,基于 Go 泛型设计,提供类型安全的映射操作,让键值对数据处理变得简单而高效。

🚀 特性亮点

  • 🧩 泛型支持: 完整的类型安全,编译时错误检查
  • 🔗 链式调用: 流畅的方法链,提高代码可读性
  • ⚡ 高性能: 优化的数据结构和算法实现
  • 🔄 函数式编程: Map、Filter、Reduce 等高阶函数
  • 📊 丰富功能: 涵盖所有常见映射操作场景
  • 🔧 易扩展: 支持自定义比较和转换函数

📦 基础用法

创建 XMap 对象

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()

🔄 函数式编程

Map 转换

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": "***"}

Filter 过滤

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}

Reduce 聚合

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

ForEach 遍历

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 请求处理

// 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

🎯 最佳实践

1. 性能优化

// ✅ 预分配容量
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)
}

2. 内存管理

// ✅ 及时释放大映射
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)       // 原地修改
}

3. 可读性优化

// ✅ 使用有意义的链式操作
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 时遇到问题:


🎉 现在您已经掌握了 XMap 的强大功能,开始在项目中使用这些优雅的映射操作吧!

⚠️ **GitHub.com Fallback** ⚠️