当前位置: 首页 > news >正文

go语言中数据接口set集合的实现

概述

set 是一种常用的数据结构,它表示一组唯一元素的集合。在不同的编程语言和库中,set 可能有不同的实现方式和特性。

set 集合数据结构具有以下特性:

  • 唯一性:set 中的元素是唯一的,不允许重复。这意味着在 set 中添加重复的元素不会产生任何变化。
  • 无序性:set 中的元素没有顺序。不能通过索引访问 set 中的元素,也不能对 set 中的元素进行排序。
  • 可变性:set 通常是可变的,这意味着你可以添加或删除元素。
  • 集合运算:set 支持多种集合运算,如并集、交集和差集。

在这里插入图片描述
(图片来源于网络,如有侵权请联系删除)

Go语言中最常用的两种数据结构分别是 slice 和 map。 除了 Go 内置的数据结构,还有一些数据结构是由 Go 的官方 container 包提供,如 heap 堆、list 双向链表和ring 回环链表。但Go语言中并没有内置set这种数据结构。本文聊聊go语言中set的实现方式。

我们知道 map 的键是具有唯一性,所以可以用 map 来实现数据结构 set。

set的实现

使用map使用一个set集合,意味着我们只关心 key 的存在,其 value 值并不重要,直接将vlaue设置为空接口。

package mainimport ("errors""fmt""sync"
)/*
用map实现一个线程安全的set
*/type void struct{}var member voidtype IData interface{}type Set struct {mapset map[IData]struct{}mutex  sync.Mutex
}func NewSet() *Set {return &Set{mapset: make(map[IData]struct{}),mutex:  sync.Mutex{},}
}func (s *Set) Add(data IData) bool {s.mutex.Lock()defer s.mutex.Unlock()s.mapset[data] = memberreturn true
}func (s *Set) Remove(data IData) error {s.mutex.Lock()defer s.mutex.Unlock()for k, _ := range s.mapset {if k == data {delete(s.mapset, k)return nil}}return errors.New("not found")
}func (s *Set) Pop() IData {s.mutex.Lock()defer s.mutex.Unlock()if len(s.mapset) <= 0 {return nil}for k, _ := range s.mapset {return s.mapset[k]}return nil
}func (s *Set) Size() int {s.mutex.Lock()defer s.mutex.Unlock()return len(s.mapset)}func (s *Set) All() []IData {s.mutex.Lock()defer s.mutex.Unlock()datas := make([]IData, 0)for k, _ := range s.mapset {datas = append(datas, k)}return datas
}func main() {// testmyset := NewSet()myset.Add(1)myset.Add(2)myset.Add(1)fmt.Println(myset.All()) // [1 2]myset.Add(3)fmt.Println(myset.Size()) //3fmt.Println(myset.All())  // [1 2 3]myset.Remove(2)fmt.Println(myset.All()) // [1 2 3]}

set的三方库

在kubernetes中也实现了stirng,int32,int43,byte等几种基本类型为值的set集合。接下来我们分析下源码实现。找到源码为位置k8s.io/apimachinery/pkg/util/sets

// sets.String is a set of strings, implemented via map[string]struct{} for minimal memory consumption.
// String类型定义,使用map来实现set集合,集合的元素是string
type String map[string]Empty// NewString creates a String from a list of values.
// 构造一个set,set集合存放的值是string类型
func NewString(items ...string) String {ss := String{}ss.Insert(items...)return ss
}// Insert adds items to the set.
// 插入元素到集合
func (s String) Insert(items ...string) String {for _, item := range items {s[item] = Empty{}}return s
}// Delete removes all items from the set.
// 从set中删除指定string
func (s String) Delete(items ...string) String {for _, item := range items {delete(s, item)}return s
}// Has returns true if and only if item is contained in the set.
// 判断set是否包含指定的string
func (s String) Has(item string) bool {_, contained := s[item]return contained
}// HasAll returns true if and only if all items are contained in the set.
// 判断set是否包括一组所有的字符串
func (s String) HasAll(items ...string) bool {for _, item := range items {if !s.Has(item) {return false}}return true
}// HasAny returns true if any items are contained in the set.
// 判断一组字符串是否有包括在set中
func (s String) HasAny(items ...string) bool {for _, item := range items {if s.Has(item) {return true}}return false
}

总结

本文介绍了set的特点,并介绍go语言中如何用map实现一个set,最后我们分析了kubernete源码中的set库的源码。由于源码比较简单,就没有展开分析。


http://www.mrgr.cn/news/1975.html

相关文章:

  • Element-03.组件-Pagination分页
  • 【k8s】master节点重新安装docker-ce
  • Visual Studio 2022 v17.11 发布
  • 后端开发刷题 | 链表内指定区间反转【链表篇】
  • 第6章 Android应用资源
  • 【EI会议】第三届环境工程与可持续能源国际会议征稿开启
  • 做跨境,东南亚市场要做哪些准备!
  • 【无标题】playbook的基本使用
  • Unity3D 自定义窗口
  • C语言——字符函数、字符串函数和内存函数
  • 基于vue框架的哀牢犁耙会助农系统r4347(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。
  • 如何选择较为安全的第三方依赖版本?
  • 前端学习Day29
  • C# String的方法
  • 美国政府紧急应对三星Galaxy手机安全漏洞
  • 借助Aapose.Cells 使用 C# 在 Excel 中读取、添加和编辑线程注释
  • Java Web —— 第六天(Mybatis)
  • 【Linux】yum、vim、gcc/g++的使用
  • 【LeetCode Cookbook(C++ 描述)】一刷二叉树综合(下)
  • C++参悟-单例模式