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  }