Golang常用数据结构Set原理及第三方库

1,373 阅读1分钟

1. 原理

依据Map键的唯一性 作为集合Set的结构支撑 再使用空结构体不占任何内存 作为值

func main() {
   set := make(map[interface{}]val)
   set["key"] = val{}
   set[1] = val{}
   delete(set, "key")
   size := len(set)
   exists := set["key"]
   fmt.Println(set, size, exists)
}

2. 第三方库使用及代码展示

package main

import (
   "fmt"
   mapset "github.com/deckarep/golang-set"
)

func main() {
   // 默认创建是线程安全的
   // 可以使用 NewThreadUnsafeSet 创建线程不安全的
   // 线程安全和不安全 只是在不安全的基础上加锁实现的线程安全
   s1 := mapset.NewSet(1, 2, 3, 4, 5)
   fmt.Println("s1 contains 3: ", s1.Contains(3))
   s1.Add("LiLong") // 添加一个元素
   fmt.Println("has ... ", s1)
   s1.Remove(5) // 移除一个元素
   fmt.Println("has ... ", s1)
   s2 := mapset.NewSet("a", "b", "c", "d", 1, 2)
   fmt.Println(s1.Union(s2))            // 并集
   fmt.Println(s1.Difference(s2))       // 差集 s1 - s2
   fmt.Println(s1.Intersect(s2))        // 交集
   fmt.Println(s1.CartesianProduct(s2)) // 笛卡尔积
   fmt.Println(s1.Equal(s2))            // 是否相等
   fmt.Println(s1.IsProperSubset(s2))   // 是否是真子集
   fmt.Println(s1.IsSubset(s2))         // 是否是子集
   fmt.Println(s1.Cardinality())        // 返回长度
   fmt.Println(s1.ToSlice())            // 转成切片Slice
   fmt.Println(s1.String())             // 是否是子集
   for val := range s1.Iter() {         // 遍历取值
      fmt.Println(val)
   }
}