支持泛型的数据结构库


Listked
是一个支持泛型的双向链表容器,提供了加锁和不加锁的实现。
package mainimport ("fmt""github.com/antlabs/gstl/linkedlist")funcmain() {// 创建一个不加锁的链表list:=linkedlist.New[int]()// 插入元素list.PushBack(1)list.PushFront(0)// 遍历链表list.Range(func(valueint) {fmt.Println(value) })// 删除元素list.Remove(0)}
package mainimport ("fmt""sync""github.com/antlabs/gstl/linkedlist")funcmain() {// 创建一个加锁的链表list:=linkedlist.NewConcurrent[int]()varwg sync.WaitGroupwg.Add(2)// 并发插入元素gofunc() {deferwg.Done()list.PushBack(1)list.PushFront(0) }()// 并发遍历链表gofunc() {deferwg.Done()list.Range(func(valueint) {fmt.Println(value) }) }()wg.Wait()// 删除元素list.Remove(0)}
- 不加锁的链表:适用于单线程环境,性能更高。
- 加锁的链表:适用于多线程环境,保证线程安全。
和标准库不同的地方是有序hash
SkipList
是一种高效的有序数据结构,支持快速的插入、删除和查找操作。
package mainimport ("fmt""github.com/antlabs/gstl/skiplist")funcmain() {// 创建一个新的 SkipListsl:=skiplist.New[int,string]()// 插入元素sl.Insert(1,"one")sl.Insert(2,"two")// 获取元素ifvalue,ok:=sl.Get(1);ok {fmt.Println("Key 1:",value) }// 删除元素sl.Delete(1)}
package mainimport ("fmt""sync""github.com/antlabs/gstl/skiplist")funcmain() {// 创建一个并发安全的 SkipListcsl:=skiplist.NewConcurrent[int,string]()varwg sync.WaitGroup// 并发插入元素wg.Add(2)gofunc() {deferwg.Done()csl.Insert(1,"one") }()gofunc() {deferwg.Done()csl.Insert(2,"two") }()wg.Wait()// 并发获取元素wg.Add(2)gofunc() {deferwg.Done()ifvalue,ok:=csl.Get(1);ok {fmt.Println("Key 1:",value) } }()gofunc() {deferwg.Done()ifvalue,ok:=csl.Get(2);ok {fmt.Println("Key 2:",value) } }()wg.Wait()}
// 声明一个bool类型的trie treet:=trie.New[bool]()// 新增一个keyt.Set("hello",true)// 获取值v:=t.Get("hello")// 检查trie中是有hello前缀的数据ok:=t.HasPrefix("hello")// 删除键t.Delete(kstring)// 返回trie中保存的元素个数t.Len()
// 声明一个string类型的sets:=set.New[string]()// 新加成员s.Set("1")s.Set("2")s.Set("3")// 查看某个变量是否存在set中s.IsMember(1)// 长度s.Len()// set转slices.ToSlice()// 深度复制一份newSet:=s.Close()// 集合取差集 s - s2s:=From("hello","world","1234","4567")s2:=From("1234","4567")newSet:=s.Diff(s2)assert.Equal(t,newSet.ToSlice(), []string{"hello","world"})// 集合取交集s:=From("1234","5678","9abc")s2:=From("abcde","5678","9abc")v:=s.Intersection(s2).ToSlice()assert.Equal(t,v, []string{"5678","9abc"})// 集合取并集s:=From("1111")s1:=From("2222")s2:=From("3333")newSet:=s.Union(s1,s2)assert.Equal(t,newSet.ToSlice(), []string{"1111","2222","3333"})// 测试集合s每个元素是否在s1里面, s <= s1s:=From("5678","9abc")s2:=From("abcde","5678","9abc")assert.True(t,s.IsSubset(s2))// 测试集合s1每个元素是否在s里面 s1 <= ss2:=From("5678","9abc")s:=From("abcde","5678","9abc")assert.True(t,s.IsSuperset(s2))// 遍历某个集合a:= []string{"1111","2222","3333"}s:=From(a...)for_,v:=rangea {s.Set(v)}s.Range(func(kstring)bool {fmt.Println(k)returntrue})// 测试两个集合是否相等 Equals:=New[int]()max:=1000fori:=0;i<max;i++ {s.Set(i)}s2:=s.Clone()assert.True(t,s.Equal(s2))
ifop是弥补下golang没有三目运算符,使用函数模拟
// 如果该值不为0, 返回原来的值,否则默认值val=IfElse(len(val)!=0,val,"default")
o:=map[string]any{"hello":"hello"}a:= []any{"hello","world"}fmt.Printf("%#v",IfElseAny(o!=nil,o,a))
薄薄一层包装,增加标准库map的接口
m:=make(map[string]string)m["a"]="1"m["b"]="2"m["c"]="3"get:=mapex.Keys(m)// 返回map的所有key
m:=make(map[string]string)m["a"]="1"m["b"]="2"m["c"]="3"get:=mapex.Values(m)
rwmap与sync.Map类似支持并发访问,只解决sync.Map 2个问题.
- 没有Len成员函数
- 以及没有使用泛型语法,有运行才发现类型使用错误的烦恼
varm rwmap.RWMap[string,string]// 声明一个string, string的mapm.Store("hello","1")// 保存v1,ok1:=m.Load("hello")// 获取值v1,ok1=m.LoadAndDelete("hello")//返回hello对应值,然后删除helloDelete("hello")// 删除v1,ok1=m.LoadOrStore("hello","world")// 遍历,使用回调函数m.Range(func(key,valstring)bool {fmt.Printf("k:%s, val:%s\n"i,key,val)returntrue})// 遍历,迭代器forpair:=rangem.Iter() {fmt.Printf("k:%s, val:%s\n",pair.Key,pair.Val)}m.Len()// 获取长度allKeys:=m.Keys()//返回所有的keyallValues:=m.Values()// 返回所有的value
cmap是用锁分区的方式实现的,(TODO优化,目前只有几个指标比sync.Map快)
varm cmap.CMap[string,string]// 声明一个string, string的mapm.Store("hello","1")// 保存v1,ok1:=m.Load("hello")// 获取值v1,ok1=m.LoadAndDelete("hello")//返回hello对应值,然后删除helloDelete("hello")// 删除v1,ok1=m.LoadOrStore("hello","world")// 遍历,使用回调函数m.Range(func(key,valstring)bool {fmt.Printf("k:%s, val:%s\n"i,key,val)returntrue})// 遍历,迭代器forpair:=rangem.Iter() {fmt.Printf("k:%s, val:%s\n",pair.Key,pair.Val)}m.Len()// 获取长度allKeys:=m.Keys()//返回所有的keyallValues:=m.Values()// 返回所有的value