golang基于LinkedHashMap实现的简单集合数据结构插件库set的使用
golang基于LinkedHashMap实现的简单集合数据结构插件库set的使用
Set是一个基于LinkedHashMap实现的简单集合数据结构库,用于处理不重复元素的集合。
功能特性
- 支持int64和string类型的集合
- 自动去除重复元素
- 保持元素插入顺序
- 提供多种集合操作方法
安装
go get github.com/StudioSol/set
使用示例
int64集合示例
package main
import (
"fmt"
"github.com/StudioSol/set"
)
func main() {
// 创建包含重复元素的int64切片
duplicatedInt64 := []int64{1, 1, 2, 2, 3, 3}
// 使用NewLinkedHashSetINT64创建集合,自动去重
unduplicatedInt64 := set.NewLinkedHashSetINT64(duplicatedInt64...)
// 将集合转换为切片
unduplicatedArray := unduplicatedInt64.AsSlice()
fmt.Println(unduplicatedArray) // 输出: [1 2 3]
// 获取集合长度
fmt.Println(unduplicatedInt64.Length()) // 输出: 3
// 向集合添加元素(自动去重)
unduplicatedInt64.Add(1, 2, 3, 4)
fmt.Println(unduplicatedInt64.AsSlice()) // 输出: [1 2 3 4]
// 检查元素是否在集合中
fmt.Println(unduplicatedInt64.InArray(1)) // 输出: true
fmt.Println(unduplicatedInt64.InArray(5)) // 输出: false
// 将集合转换为interface{}切片
interfaceList := unduplicatedInt64.AsInterface()
fmt.Println(interfaceList) // 输出: [1 2 3 4]
// 遍历集合
for i := range unduplicatedInt64.Iter() {
fmt.Println(i)
}
// 从集合中移除元素
unduplicatedInt64.Remove(0, 1, 2, 3)
fmt.Println(unduplicatedInt64.AsSlice()) // 输出: [4]
}
string集合示例
package main
import (
"fmt"
"github.com/StudioSol/set"
)
func main() {
// 创建包含重复字符串的切片
duplicatedStrings := []string{"apple", "apple", "banana", "banana", "orange"}
// 使用NewLinkedHashSetString创建集合
stringSet := set.NewLinkedHashSetString(duplicatedStrings...)
// 输出去重后的结果
fmt.Println(stringSet.AsSlice()) // 输出: [apple banana orange]
// 添加新元素
stringSet.Add("grape", "apple", "mango")
fmt.Println(stringSet.AsSlice()) // 输出: [apple banana orange grape mango]
// 检查元素是否存在
fmt.Println(stringSet.InArray("banana")) // 输出: true
fmt.Println(stringSet.InArray("pear")) // 输出: false
// 移除元素
stringSet.Remove("apple", "orange")
fmt.Println(stringSet.AsSlice()) // 输出: [banana grape mango]
}
主要方法
NewLinkedHashSetINT64(...int64)
- 创建int64集合NewLinkedHashSetString(...string)
- 创建string集合Add(...)
- 添加元素Remove(...)
- 移除元素AsSlice()
- 转换为切片AsInterface()
- 转换为interface{}切片Length()
- 获取集合长度InArray()
- 检查元素是否存在Iter()
- 获取可迭代的集合
这个库提供了简单易用的集合操作功能,特别适合需要保持元素插入顺序且需要去重的场景。
更多关于golang基于LinkedHashMap实现的简单集合数据结构插件库set的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang基于LinkedHashMap实现的简单集合数据结构插件库set的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Golang 基于 LinkedHashMap 实现的 Set 集合库
在 Golang 标准库中没有提供 Set 集合的实现,但我们可以基于 container/list
和 map
来实现一个类似 Java 中 LinkedHashSet 的有序集合。下面我将介绍一个简单的实现方案。
基本实现
package set
import (
"container/list"
"fmt"
)
// LinkedHashSet 基于LinkedHashMap实现的有序集合
type LinkedHashSet struct {
dataMap map[interface{}]*list.Element // 用于快速查找
dataList *list.List // 用于维护插入顺序
}
// NewLinkedHashSet 创建一个新的LinkedHashSet
func NewLinkedHashSet() *LinkedHashSet {
return &LinkedHashSet{
dataMap: make(map[interface{}]*list.Element),
dataList: list.New(),
}
}
// Add 添加元素到集合中
func (s *LinkedHashSet) Add(value interface{}) bool {
if _, exists := s.dataMap[value]; exists {
return false // 元素已存在
}
element := s.dataList.PushBack(value)
s.dataMap[value] = element
return true
}
// Remove 从集合中移除元素
func (s *LinkedHashSet) Remove(value interface{}) bool {
element, exists := s.dataMap[value]
if !exists {
return false // 元素不存在
}
s.dataList.Remove(element)
delete(s.dataMap, value)
return true
}
// Contains 检查集合是否包含指定元素
func (s *LinkedHashSet) Contains(value interface{}) bool {
_, exists := s.dataMap[value]
return exists
}
// Size 返回集合大小
func (s *LinkedHashSet) Size() int {
return s.dataList.Len()
}
// Clear 清空集合
func (s *LinkedHashSet) Clear() {
s.dataList = list.New()
s.dataMap = make(map[interface{}]*list.Element)
}
// ToSlice 将集合转换为切片
func (s *LinkedHashSet) ToSlice() []interface{} {
slice := make([]interface{}, 0, s.dataList.Len())
for element := s.dataList.Front(); element != nil; element = element.Next() {
slice = append(slice, element.Value)
}
return slice
}
// String 实现Stringer接口
func (s *LinkedHashSet) String() string {
return fmt.Sprintf("%v", s.ToSlice())
}
// Iterator 返回一个迭代器
func (s *LinkedHashSet) Iterator() *Iterator {
return &Iterator{
current: s.dataList.Front(),
}
}
// Iterator 集合迭代器
type Iterator struct {
current *list.Element
}
// Next 移动到下一个元素
func (it *Iterator) Next() bool {
if it.current == nil {
return false
}
it.current = it.current.Next()
return it.current != nil
}
// Value 获取当前元素值
func (it *Iterator) Value() interface{} {
if it.current == nil {
return nil
}
return it.current.Value
}
使用示例
package main
import (
"fmt"
"yourpackage/set"
)
func main() {
// 创建一个新的有序集合
s := set.NewLinkedHashSet()
// 添加元素
s.Add("apple")
s.Add("banana")
s.Add("orange")
s.Add("apple") // 重复添加会被忽略
fmt.Println("集合内容:", s) // 集合内容: [apple banana orange]
fmt.Println("集合大小:", s.Size()) // 集合大小: 3
// 检查元素是否存在
fmt.Println("包含 'banana':", s.Contains("banana")) // true
fmt.Println("包含 'grape':", s.Contains("grape")) // false
// 移除元素
s.Remove("banana")
fmt.Println("移除 'banana' 后:", s) // [apple orange]
// 迭代集合
fmt.Println("迭代集合:")
it := s.Iterator()
for it.Value() != nil {
fmt.Println(it.Value())
if !it.Next() {
break
}
}
// 转换为切片
slice := s.ToSlice()
fmt.Printf("转换为切片: %v (类型: %T)\n", slice, slice)
// 清空集合
s.Clear()
fmt.Println("清空后集合大小:", s.Size()) // 0
}
功能特点
- 有序性:保持元素的插入顺序
- 唯一性:保证集合中元素的唯一性
- 高效操作:
- 添加/删除/查找操作的时间复杂度都是 O(1)
- 迭代支持:可以通过迭代器遍历集合
- 类型安全:使用泛型可以进一步增强类型安全
扩展建议
- 泛型支持:在 Go 1.18+ 中可以使用泛型使集合类型安全
- 并发安全:添加 sync.RWMutex 实现线程安全版本
- 更多集合操作:实现并集、交集、差集等操作
- JSON 序列化:实现 MarshalJSON/UnmarshalJSON 方法
这个简单的实现已经能满足大多数 Set 集合的使用场景,如果需要更复杂的功能,可以考虑使用第三方库如 github.com/deckarep/golang-set
。