分享
golang实现set集合,变相实现切片去重
u012210379 · · 19500 次点击 · · 开始浏览这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。
原文地址:http://www.jb51.net/article/56828.htm,本文抽取出了set的部分,并对无伤大雅的小错误进行了修改
java中有set集合,而golang没有,今天突然有个需求要对一堆int切片进行组合去重,郁闷好久,自己的土办法时间复杂度实在太高,看到上面那个帖子感觉好高兴:
- golang中的map是不允许重复的,看这段代码
m := map[string]string{ "1": "one", "2": "two", "3": "three", } fmt.Println(m)//输出map[1:one 2:two 3:three]如果我写成这个样子m := map[string]string{ "1": "one", "2": "two", "1": "one", "3": "three", } fmt.Println(m)程序直接报错:duplicate key "1" in map literal - 通过上面的小例子,说明golang的map是不允许键重复的,详细说明见http://golanghome.com/post/155 和 http://www.tuicool.com/articles/RrINZv
- 以上都不是重点
- 那么根据map的特性,就可以仿造出java中的set集合,再次感谢原文http://www.jb51.net/article/56828.htm 其中我添加了对返回结果的排序,虽然只是调用了个系统函数,但是感觉好爽啊 运行测试已通过
package main import ( "fmt" "sort" "sync" ) type Set struct { m map[int]bool sync.RWMutex } func New() *Set { return &Set{ m: map[int]bool{}, } } func (s *Set) Add(item int) { s.Lock() defer s.Unlock() s.m[item] = true } func (s *Set) Remove(item int) { s.Lock() defer s.Unlock() delete(s.m, item) } func (s *Set) Has(item int) bool { s.RLock() defer s.RUnlock() _, ok := s.m[item] return ok } func (s *Set) Len() int { return len(s.List()) } func (s *Set) Clear() { s.Lock() defer s.Unlock() s.m = map[int]bool{} } func (s *Set) IsEmpty() bool { if s.Len() == 0 { return true } return false } func (s *Set) List() []int { s.RLock() defer s.RUnlock() list := []int{} for item := range s.m { list = append(list, item) } return list } func (s *Set) SortList() []int { s.RLock() defer s.RUnlock() list := []int{} for item := range s.m { list = append(list, item) } sort.Ints(list) return list } func main() { //初始化 s := New() s.Add(1) s.Add(1) s.Add(0) s.Add(2) s.Add(4) s.Add(3) s.Clear() if s.IsEmpty() { fmt.Println("0 item") } s.Add(1) s.Add(2) s.Add(3) if s.Has(2) { fmt.Println("2 does exist") } s.Remove(2) s.Remove(3) fmt.Println("无序的切片", s.List()) fmt.Println("有序的切片", s.SortList()) }
有疑问加站长微信联系(非本文作者)
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
关注微信19500 次点击
添加一条新回复
(您需要 后才能回复 没有账号 ?)
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码` - 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传
收入到我管理的专栏 新建专栏
原文地址:http://www.jb51.net/article/56828.htm,本文抽取出了set的部分,并对无伤大雅的小错误进行了修改
java中有set集合,而golang没有,今天突然有个需求要对一堆int切片进行组合去重,郁闷好久,自己的土办法时间复杂度实在太高,看到上面那个帖子感觉好高兴:
- golang中的map是不允许重复的,看这段代码
m := map[string]string{ "1": "one", "2": "two", "3": "three", } fmt.Println(m)//输出map[1:one 2:two 3:three]如果我写成这个样子m := map[string]string{ "1": "one", "2": "two", "1": "one", "3": "three", } fmt.Println(m)程序直接报错:duplicate key "1" in map literal - 通过上面的小例子,说明golang的map是不允许键重复的,详细说明见http://golanghome.com/post/155 和 http://www.tuicool.com/articles/RrINZv
- 以上都不是重点
- 那么根据map的特性,就可以仿造出java中的set集合,再次感谢原文http://www.jb51.net/article/56828.htm 其中我添加了对返回结果的排序,虽然只是调用了个系统函数,但是感觉好爽啊 运行测试已通过
package main import ( "fmt" "sort" "sync" ) type Set struct { m map[int]bool sync.RWMutex } func New() *Set { return &Set{ m: map[int]bool{}, } } func (s *Set) Add(item int) { s.Lock() defer s.Unlock() s.m[item] = true } func (s *Set) Remove(item int) { s.Lock() defer s.Unlock() delete(s.m, item) } func (s *Set) Has(item int) bool { s.RLock() defer s.RUnlock() _, ok := s.m[item] return ok } func (s *Set) Len() int { return len(s.List()) } func (s *Set) Clear() { s.Lock() defer s.Unlock() s.m = map[int]bool{} } func (s *Set) IsEmpty() bool { if s.Len() == 0 { return true } return false } func (s *Set) List() []int { s.RLock() defer s.RUnlock() list := []int{} for item := range s.m { list = append(list, item) } return list } func (s *Set) SortList() []int { s.RLock() defer s.RUnlock() list := []int{} for item := range s.m { list = append(list, item) } sort.Ints(list) return list } func main() { //初始化 s := New() s.Add(1) s.Add(1) s.Add(0) s.Add(2) s.Add(4) s.Add(3) s.Clear() if s.IsEmpty() { fmt.Println("0 item") } s.Add(1) s.Add(2) s.Add(3) if s.Has(2) { fmt.Println("2 does exist") } s.Remove(2) s.Remove(3) fmt.Println("无序的切片", s.List()) fmt.Println("有序的切片", s.SortList()) }