Go语言-技巧set类实现

利用slice和map实现了个非线程安全的LinkedSet,map的value是元素的index。也支持排序。代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
package collections

import (
"encoding/json"
"fmt"
"sort"
)

// Set LinkedHashSet 支持数组排序
type Set struct {
m map[interface{}]int //元素和索引映射
list []interface{} //元素数组
compare func(i, j interface{}) bool //排序函数
}

// NewSet 构造方法
func NewSet() *Set {
s := new(Set)
s.initEle()
return s
}

// initEle 初始化数组元素
func (set *Set) initEle() {
set.m = make(map[interface{}]int)
set.list = make([]interface{}, 0)
}

// SortAble 设置排序依据
// compare--用于排序
func (set *Set) SortAble(compare func(i, j interface{}) bool) *Set {
set.compare = compare
return set
}

// Add 添加元素
func (set *Set) Add(keys ...interface{}) *Set {
//set.Lock()
//defer set.Unlock()
for _, key := range keys {
if _, ok := set.m[key]; !ok {
set.list = append(set.list, key)
set.m[key] = len(set.list) - 1
}
}
return set
}

// Delete 删除元素
func (set *Set) Delete(keys ...interface{}) {
//set.Lock()
//defer set.Unlock()
for _, key := range keys {
if v, ok := set.m[key]; !ok {
if len(set.list)-1 < v {
set.list = append(set.list[0:v], set.list[v+1:]...)
}
delete(set.m, key)
}
}
}

// Get 获取元素
func (set *Set) Get(key interface{}) interface{} {
//set.RLock()
//defer set.RUnlock()
if v, ok := set.m[key]; ok {
return set.list[v]
}
return nil
}

// Contains 获取元素
func (set *Set) Contains(key interface{}) bool {
//set.RLock()
//defer set.RUnlock()
_, ok := set.m[key]
return ok
}

// IndexOf 获取元素下标
func (set *Set) IndexOf(key interface{}) int {
//set.RLock()
//defer set.RUnlock()
if i, ok := set.m[key]; ok {
return i
}
return -1
}

// Any 多个元素有人一个true 则为true
func (set *Set) Any(cond func(key interface{}) bool) bool {
//set.RLock()
//defer set.RUnlock()
for _, key := range set.list {
if cond(key) {
return true
}
}
return false
}

// Diff 查看俩个set不同的元素,返回新的set
func (set *Set) Diff(dest *Set) *Set {
result := NewSet()
set.Foreach(func(ele interface{}) {
if dest == nil || dest.Size() == 0 || !dest.Contains(ele) {
result.Add(ele)
}
})

if dest != nil && dest.Size() > 0 {
dest.Foreach(func(ele interface{}) {
if !set.Contains(ele) {
result.Add(ele)
}
})
}
return result
}

// Difference 取s和dest差集,返回新的set
func (set *Set) Difference(dest *Set) *Set {
result := NewSet()
set.Foreach(func(ele interface{}) {
if dest == nil || dest.Size() == 0 || !dest.Contains(ele) {
result.Add(ele)
}
})
return result
}

// Union 取交集,返回新的set
func (set *Set) Union(dest *Set) *Set {
result := NewSet()
set.Foreach(func(ele interface{}) {
if dest != nil && dest.Size() > 0 && dest.Contains(ele) {
result.Add(ele)
}
})
return result
}

// Size 返回set的size
func (set *Set) Size() int {
//set.RLock()
//defer set.RUnlock()
return len(set.list)
}

// Elements 返回element列表
func (set *Set) Elements() []interface{} {
//set.RLock()
//defer set.RUnlock()
return set.list
}

// SetIterateFunc 遍历的handler
type SetIterateFunc func(interface{})

// Foreach 遍历
func (set *Set) Foreach(foreach SetIterateFunc) {
//set.RLock()
//defer set.RUnlock()
if len(set.list) == 0 {
return
}
for _, item := range set.list {
foreach(item)
}
}

// Sort 排序
func (set *Set) Sort() {
//set.Lock()
//defer set.Unlock()
sort.Sort(set)
}

func (set *Set) Swap(i, j int) {
set.list[i], set.list[j] = set.list[j], set.list[i]
set.m[set.list[i]] = i
set.m[set.list[j]] = j
}
func (set *Set) Len() int { return len(set.list) }
func (set *Set) Less(i, j int) bool {
if set.compare == nil {
return false
}
return set.compare(set.list[i], set.list[j])
}

// SetIsEmpty 判断set是否为空
func SetIsEmpty(set *Set) bool {
return set == nil || set.Size() == 0
}

// MarshalJSON 实现json.Marshaler接口
func (set *Set) MarshalJSON() ([]byte, error) {
return json.Marshal(set.list)
}

// UnmarshalJSON 实现json.Unmarshaler接口
func (set *Set) UnmarshalJSON(b []byte) error {
set.initEle()
var ele []interface{}
err := json.Unmarshal(b, &ele)
if err != nil {
return err
}
set.Add(ele...)
return err
}

//////////////////////////////////////////
func (set Set) String() string {
return fmt.Sprintf("%v", set.list)
}

排序方法的使用方法

1
2
3
4
5
s:=set.NewSet().Add(....).AddOrderBy(OrderByHandlerFunc(i,j interface{})bool{
//排序逻辑
return true
})
sort(s)