Go实现Set类型

由于Go中没有提供Set类型,所以可以自己实现一个类似Java中的Set集合

package main

import (
	"fmt"
)

// Set 定义一个泛型集合
type Set[T comparable] struct {
	data map[T]struct{}
}

// NewSet 创建一个空集合
func NewSet[T comparable]() *Set[T] {
	return &Set[T]{data: make(map[T]struct{})}
}

// Add 添加元素
func (s *Set[T]) Add(elem T) {
	s.data[elem] = struct{}{}
}

// Remove 删除元素
func (s *Set[T]) Remove(elem T) {
	delete(s.data, elem)
}

// Contains 判断元素是否存在
func (s *Set[T]) Contains(elem T) bool {
	_, ok := s.data[elem]
	return ok
}

// Size 返回集合大小
func (s *Set[T]) Size() int {
	return len(s.data)
}

// Values 返回所有元素(切片)
func (s *Set[T]) Values() []T {
	values := make([]T, 0, len(s.data))
	for k := range s.data {
		values = append(values, k)
	}
	return values
}

// Union 并集
func (s *Set[T]) Union(other *Set[T]) *Set[T] {
	result := NewSet[T]()
	for k := range s.data {
		result.Add(k)
	}
	for k := range other.data {
		result.Add(k)
	}
	return result
}

// Intersect 交集
func (s *Set[T]) Intersect(other *Set[T]) *Set[T] {
	result := NewSet[T]()
	for k := range s.data {
		if other.Contains(k) {
			result.Add(k)
		}
	}
	return result
}

// Difference 差集
func (s *Set[T]) Difference(other *Set[T]) *Set[T] {
	result := NewSet[T]()
	for k := range s.data {
		if !other.Contains(k) {
			result.Add(k)
		}
	}
	return result
}

func main() {
	s1 := NewSet[int]()
	s1.Add(1)
	s1.Add(2)
	s1.Add(3)

	s2 := NewSet[int]()
	s2.Add(3)
	s2.Add(4)

	fmt.Println("s1:", s1.Values())
	fmt.Println("s2:", s2.Values())
	fmt.Println("并集:", s1.Union(s2).Values())
	fmt.Println("交集:", s1.Intersect(s2).Values())
	fmt.Println("差集:", s1.Difference(s2).Values())
}