github.com/searKing/golang/go@v1.2.74/container/set/set.go (about) 1 // Copyright 2020 The searKing Author. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package set 6 7 import ( 8 "github.com/searKing/golang/go/container/slice" 9 "github.com/searKing/golang/go/util/object" 10 ) 11 12 // take advantage of map 13 type Set struct { 14 elems map[interface{}]struct{} 15 } 16 17 // Create a new set 18 func New() *Set { 19 return &Set{} 20 } 21 22 func (s *Set) Init() *Set { 23 s.elems = make(map[interface{}]struct{}) 24 return s 25 } 26 27 // lazyInit lazily initializes a zero List value. 28 func (s *Set) lazyInit() *Set { 29 if s.elems == nil { 30 s.Init() 31 } 32 return s 33 } 34 35 // Count returns the number of elements in this set (its cardinality). 36 func (s *Set) Count() int { 37 if s.elems == nil { 38 return 0 39 } 40 return len(s.elems) 41 } 42 43 // IsEmpty returns {@code true} if this set contains no elements. 44 func (s *Set) IsEmpty() bool { 45 if s.Count() == 0 { 46 return true 47 } 48 return false 49 } 50 51 // Contains returns {@code true} if this set contains the specified element. 52 func (s *Set) Contains(e interface{}) bool { 53 if s.IsEmpty() { 54 return false 55 } 56 if _, ok := s.elems[e]; ok { 57 return true 58 } 59 return false 60 } 61 62 // ToSLice returns a slice containing all of the elements in this set. 63 func (s *Set) ToSlice() []interface{} { 64 es := make([]interface{}, 0, s.Count()) 65 if s.IsEmpty() { 66 return es 67 } 68 for e, _ := range s.elems { 69 es = append(es, e) 70 } 71 return es 72 } 73 74 // Add adds the specified element to this set if it is not already present. 75 func (s *Set) Add(e interface{}) *Set { 76 s.lazyInit() 77 s.elems[e] = struct{}{} 78 return s 79 } 80 81 // Remove removes the specified element from this set if it is present. 82 func (s *Set) Remove(e interface{}) *Set { 83 if !s.Contains(e) { 84 return s 85 } 86 delete(s.elems, e) 87 return s 88 } 89 90 // ContainsAll returns {@code true} {@code true} if this set contains all of the elements of the specified collection. 91 func (s *Set) ContainsAll(stream *slice.Stream) bool { 92 object.RequireNonNil(stream) 93 if s.IsEmpty() { 94 return false 95 } 96 for k, _ := range s.elems { 97 if stream.NoneMatch(func(e interface{}) bool { 98 if e == k { 99 return true 100 } 101 return false 102 }) { 103 return false 104 } 105 } 106 return true 107 } 108 109 // AddAll adds all of the elements in the specified collection to this set if 110 // they're not already present (optional operation). 111 func (s *Set) AddAll(stream *slice.Stream) *Set { 112 object.RequireNonNil(stream) 113 stream.ForEach(func(e interface{}) { 114 s.Add(e) 115 }) 116 return s 117 } 118 119 // AddAll adds all of the elements in the specified collection to this set if 120 // they're not already present (optional operation). 121 // <p>This operation processes the elements one at a time, in encounter 122 // order if one exists. Performing the action for one element 123 // performing the action for subsequent elements, but for any given element, 124 // the action may be performed in whatever thread the library chooses. 125 func (s *Set) AddAllOrdered(stream *slice.Stream) *Set { 126 object.RequireNonNil(stream) 127 stream.ForEachOrdered(func(e interface{}) { 128 s.Add(e) 129 }) 130 return s 131 } 132 133 // RetainAll retains only the elements in this set that are contained in the 134 // specified collection (optional operation). In other words, removes 135 // from this set all of its elements that are not contained in the 136 // specified collection. 137 func (s *Set) RetainAll(stream *slice.Stream) *Set { 138 object.RequireNonNil(stream) 139 if s.IsEmpty() { 140 return s 141 } 142 // stream is too big 143 retained := stream.Filter(func(e interface{}) bool { 144 _, ok := s.elems[e] 145 return ok 146 }) 147 s.Clear() 148 s.AddAll(retained) 149 return s 150 } 151 152 // RemoveAll removes from this set all of its elements that are contained in the 153 // specified collection (optional operation). If the specified 154 // collection is also a set, this operation effectively modifies this 155 // set so that its value is the <i>asymmetric set difference</i> of 156 // the two sets. 157 func (s *Set) RemoveAll(stream *slice.Stream) *Set { 158 object.RequireNonNil(stream) 159 if s.IsEmpty() { 160 return s 161 } 162 stream.ForEachOrdered(func(e interface{}) { 163 if s.Contains(e) { 164 s.Remove(e) 165 } 166 }) 167 return s 168 } 169 170 // Clear removes all of the elements from this set (optional operation). 171 // The set will be empty after this call returns. 172 func (s *Set) Clear() *Set { 173 s.elems = nil 174 return s 175 } 176 177 // Compares the specified object with this set for equality. Returns 178 // {@code true} if the specified object is also a set, the two sets 179 // have the same size, and every member of the specified set is 180 // contained in this set (or equivalently, every member of this set is 181 // contained in the specified set). 182 func (s *Set) Equals(other *Set) bool { 183 object.RequireNonNil(other) 184 if s == other { 185 return true 186 } 187 188 if s.IsEmpty() != other.IsEmpty() { 189 return false 190 } 191 192 if s.Count() != other.Count() { 193 return false 194 } 195 for k, _ := range s.elems { 196 if !other.Contains(k) { 197 return false 198 } 199 } 200 return true 201 } 202 203 // Clone returns a deepcopy of it's self 204 func (s *Set) Clone() *Set { 205 return (object.DeepClone(s)).(*Set) 206 } 207 208 func (s *Set) ToStream() *slice.Stream { 209 return slice.NewStream().WithSlice(s.ToSlice()) 210 } 211 212 // Of returns an unmodifiable set containing the input element(s). 213 func Of(es ...interface{}) *Set { 214 s := New() 215 slice.NewStream().WithSlice(es).ForEachOrdered( 216 func(e interface{}) { 217 s.Add(e) 218 }) 219 return s 220 } 221 222 //grammar surger for count 223 func (s *Set) Size() int { 224 return s.Count() 225 } 226 227 func (s *Set) Length() int { 228 return s.Count() 229 }