1 Star 0 Fork 0

李爽 / go-object

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
strings.go 9.39 KB
一键复制 编辑 原始数据 按行查看 历史
// Package object 将字符串切片封装为对象,提供线程安全的操作方法
package object
import ( // 导入依赖的包
"sort" // 导入排序相关功能的包
"strings" // 导入字符串处理相关功能的包
"sync" // 导入同步机制相关功能的包(如互斥锁)
)
// stringSliceLocker 接口,包含锁的基本操作方法
type stringSliceLocker interface {
Lock() // 加锁操作
Unlock() // 解锁操作
RLock() // 读锁操作
RUnlock() // 读解锁操作
}
// stringSliceNotLocker 实现stringSliceLocker接口的方法,但方法为空
type stringSliceNotLocker struct{}
func (stringSliceNotLocker) Lock() {} // 实现加锁操作,无实际操作
func (stringSliceNotLocker) Unlock() {} // 实现解锁操作,无实际操作
func (stringSliceNotLocker) RLock() {} // 实现读锁操作,无实际操作
func (stringSliceNotLocker) RUnlock() {} // 实现读解锁操作,无实际操作
// stringSliceSafeLocker 内嵌sync.RWMutex来保证线程安全
type stringSliceSafeLocker struct {
locker sync.RWMutex // 声明一个读写互斥锁
}
func (l *stringSliceSafeLocker) Lock() { l.locker.Lock() } // 实现加锁操作
func (l *stringSliceSafeLocker) Unlock() { l.locker.Unlock() } // 实现解锁操作
func (l *stringSliceSafeLocker) RLock() { l.locker.RLock() } // 实现读锁操作
func (l *stringSliceSafeLocker) RUnlock() { l.locker.RUnlock() } // 实现读解锁操作
// StringSlice 结构体,用于存储字符串切片,并通过locker来控制线程安全
type StringSlice struct {
Values []string // 存储实际的字符串切片数据
locker stringSliceLocker // 使用stringSliceLocker接口实现锁定机制
}
// NewStringSlice 函数创建StringSlice实例,可以选择是否线程安全
func NewStringSlice(values []string, threadSafe bool) *StringSlice {
deduplicatedValues := removeDuplicates(values) // 对初始切片去重
s := &StringSlice{Values: deduplicatedValues} // 创建StringSlice实例,设置去重后的数据
if threadSafe {
s.locker = &stringSliceSafeLocker{} // 如果需要线程安全,则设置locker为StringSliceSafeLocker
} else {
s.locker = stringSliceNotLocker{} // 否则设置为不进行任何操作的locker
}
return s // 返回创建的StringSlice实例
}
// Set 方法设置切片的值
func (s *StringSlice) Set(values []string) {
s.locker.Lock() // 加锁
defer s.locker.Unlock() // 方法最后解锁
s.Values = values // 设置Values为传入的切片
}
// Get 方法获取切片的值
func (s *StringSlice) Get() []string {
s.locker.RLock() // 读锁
defer s.locker.RUnlock() // 方法最后读解锁
return s.Values // 返回Values切片
}
// Remove 方法根据值移除元素
func (s *StringSlice) Remove(value string, allowChangeOrder bool) {
s.locker.Lock() // 加锁
var indices []int // 用于存储需要删除的元素索引
for i, v := range s.Values {
if v == value {
indices = append(indices, i) // 如果找到需要删除的值,将索引添加到indices切片中
}
}
s.locker.Unlock() // 解锁
if len(indices) > 0 {
s.RemoveAtIndices(indices, allowChangeOrder) // 如果找到需要删除的元素,根据索引移除
}
}
// RemoveAtIndex 方法根据索引移除元素
func (s *StringSlice) RemoveAtIndex(index int, allowChangeOrder bool) {
s.locker.Lock() // 加锁
defer s.locker.Unlock() // 方法最后解锁
if allowChangeOrder {
s.Values[index] = s.Values[len(s.Values)-1] // 如果允许改变顺序,将最后一个元素移动到待删除元素的位置
s.Values = s.Values[:len(s.Values)-1] // 缩减切片大小,移除最后一个元素
} else {
s.Values = append(s.Values[:index], s.Values[index+1:]...) // 不允许改变顺序,直接移除元素
}
}
// RemoveAtIndices 方法根据一组索引移除多个元素
func (s *StringSlice) RemoveAtIndices(indices []int, allowChangeOrder bool) {
if allowChangeOrder {
toBeRemoved := make(map[int]bool) // 创建一个map来标记待删除元素
for _, index := range indices {
toBeRemoved[index] = true // 标记待删除元素
}
s.locker.Lock() // 加锁
newValues := s.Values[:0] // 创建新的切片,用于存储未被删除的元素
for i, value := range s.Values {
if !toBeRemoved[i] {
newValues = append(newValues, value) // 如果当前索引不在待删除map中,则将元素添加到新切片中
}
}
s.Values = newValues // 更新Values为没有被删除元素的新切片
s.locker.Unlock() // 解锁
} else {
sort.Sort(sort.Reverse(sort.IntSlice(indices))) // 如果不允许改变顺序,先对索引进行降序排序
for _, index := range indices {
s.RemoveAtIndex(index, false) // 逐个索引移除元素
}
}
}
// Clean 方法清空切片
func (s *StringSlice) Clean() {
s.locker.Lock() // 加锁
defer s.locker.Unlock() // 方法最后解锁
s.Values = nil // 将Values设置为nil,即清空切片
}
// Contains 方法判断切片中是否包含关键字
func (s *StringSlice) Contains(keyword string) bool {
s.locker.RLock() // 读锁
defer s.locker.RUnlock() // 方法最后读解锁
for _, v := range s.Values {
if strings.Contains(v, keyword) {
return true // 如果找到包含关键字的元素,返回true
}
}
return false // 否则返回false
}
// ExactMatch 方法判断切片中是否有元素与关键字完全匹配
func (s *StringSlice) ExactMatch(keyword string) bool {
s.locker.RLock() // 读锁
defer s.locker.RUnlock() // 方法最后读解锁
for _, v := range s.Values {
if v == keyword {
return true // 如果找到完全匹配的元素,返回true
}
}
return false // 否则返回false
}
// Size 方法返回切片的长度
func (s *StringSlice) Size() int {
s.locker.RLock() // 读锁
defer s.locker.RUnlock() // 方法最后读解锁
return len(s.Values) // 返回Values的长度
}
// Add 方法向切片中添加一个元素
func (s *StringSlice) Add(item string) {
s.locker.Lock() // 加锁
defer s.locker.Unlock() // 方法最后解锁
s.Values = append(s.Values, item) // 将元素添加到Values切片的末尾
}
// RemoveIfNotContains 方法移除切片中不包含关键字的元素
func (s *StringSlice) RemoveIfNotContains(keyword string) {
s.locker.Lock() // 加锁
defer s.locker.Unlock() // 方法最后解锁
i := 0 // 初始化索引
for i < len(s.Values) {
if !strings.Contains(s.Values[i], keyword) {
// 如果当前元素不包含关键字,替换为最后一个元素,并缩短切片长度
s.Values[i] = s.Values[len(s.Values)-1]
s.Values = s.Values[:len(s.Values)-1]
} else {
// 如果包含关键字,索引递增
i++
}
}
}
// RemoveIfContains 方法移除切片中包含关键字的元素
func (s *StringSlice) RemoveIfContains(keyword string) {
s.locker.Lock() // 加锁
defer s.locker.Unlock() // 方法最后解锁
i := 0 // 初始化索引
for i < len(s.Values) {
if strings.Contains(s.Values[i], keyword) {
// 如果当前元素包含关键字,替换为最后一个元素,并缩短切片长度
s.Values[i] = s.Values[len(s.Values)-1]
s.Values = s.Values[:len(s.Values)-1]
} else {
// 如果不包含关键字,索引递增
i++
}
}
}
// Search 方法返回包含关键字的所有元素及其索引
func (s *StringSlice) Search(keyword string) map[int]string {
s.locker.RLock() // 读锁
defer s.locker.RUnlock() // 方法最后读解锁
result := make(map[int]string) // 创建一个map存储结果
for i, v := range s.Values {
if strings.Contains(v, keyword) {
result[i] = v // 如果元素包含关键字,添加到结果map中
}
}
return result // 返回包含关键字的元素及其索引的map
}
// Clone 方法创建并返回一个当前副本
func (s *StringSlice) Clone(threadSafe bool) *StringSlice {
s.locker.RLock() // 读锁
defer s.locker.RUnlock() // 方法最后读解锁
clone := make([]string, len(s.Values)) // 创建一个与当前Values相同长度的切片
copy(clone, s.Values) // 复制当前Values的元素到新切片
return NewStringSlice(clone, threadSafe) // 使用新切片和threadSafe参数创建新的StringSlice实例,并返回
}
// AppendWithoutDuplicates 方法将新元素添加到切片中,同时确保没有重复
func (s *StringSlice) AppendWithoutDuplicates(newItems []string) {
s.locker.RLock() // 读锁
originalValues := s.Get() // 获取当前的Values复本
s.locker.RUnlock() // 方法最后读解锁
// 将原始值和新元素合并后去重
mergedAndDeduplicated := removeDuplicates(append(originalValues, newItems...))
s.locker.Lock() // 加锁
defer s.locker.Unlock() // 方法最后解锁
s.Values = mergedAndDeduplicated // 设置Values为合并后去重的切片
}
// removeDuplicates 函数用于去除字符串切片中的重复元素
func removeDuplicates(slice []string) []string {
dedup := make([]string, 0, len(slice)) // 创建一个新切片用于存储去重后的结果
seen := make(map[string]bool) // 创建一个map记录已经看到的元素
for _, val := range slice {
if !seen[val] {
seen[val] = true // 标记元素已看到
dedup = append(dedup, val) // 将未重复的元素添加到新切片中
}
}
return dedup // 返回去重后的切片
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/love_bass/go-object.git
git@gitee.com:love_bass/go-object.git
love_bass
go-object
go-object
v1.0.5

搜索帮助

344bd9b3 5694891 D2dac590 5694891