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/listmap 来实现一个类似 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
}

功能特点

  1. 有序性:保持元素的插入顺序
  2. 唯一性:保证集合中元素的唯一性
  3. 高效操作
    • 添加/删除/查找操作的时间复杂度都是 O(1)
  4. 迭代支持:可以通过迭代器遍历集合
  5. 类型安全:使用泛型可以进一步增强类型安全

扩展建议

  1. 泛型支持:在 Go 1.18+ 中可以使用泛型使集合类型安全
  2. 并发安全:添加 sync.RWMutex 实现线程安全版本
  3. 更多集合操作:实现并集、交集、差集等操作
  4. JSON 序列化:实现 MarshalJSON/UnmarshalJSON 方法

这个简单的实现已经能满足大多数 Set 集合的使用场景,如果需要更复杂的功能,可以考虑使用第三方库如 github.com/deckarep/golang-set

回到顶部