package datastructure import ( "reflect" "sort" "sync" ) type CopyOnWriteList[T any] struct { data []T lock sync.Locker } // NewCopyOnWriteList Creates an empty list. func NewCopyOnWriteList[T any](data []T) *CopyOnWriteList[T] { return &CopyOnWriteList[T]{data: data, lock: &sync.RWMutex{}} } func (c *CopyOnWriteList[T]) getList() []T { return c.data } func (c *CopyOnWriteList[T]) setList(data []T) { c.data = data } // Size returns the number of elements in this list. func (c *CopyOnWriteList[T]) Size() int { return len(c.getList()) } // IsEmpty returns true if this list contains no elements. func (c *CopyOnWriteList[T]) IsEmpty() bool { return c.Size() == 0 } // Contain returns true if this list contains the specified element. func (c *CopyOnWriteList[T]) Contain(e T) bool { list := c.getList() return indexOf(e, list, 0, c.Size()) >= 0 } // ValueOf returns the index of the first occurrence of the specified element in this list, or null if this list does not contain the element. func (c *CopyOnWriteList[T]) ValueOf(index int) (*T, bool) { list := c.getList() if index < 0 || index >= len(c.data) { return nil, false } return get(list, index), true } // IndexOf returns the index of the first occurrence of the specified element in this list, or -1 if this list does not contain the element. func (c *CopyOnWriteList[T]) IndexOf(e T) int { list := c.getList() return indexOf(e, list, 0, c.Size()) } // indexOf returns the index of the first occurrence of the specified element in this list, or -1 if this list does not contain the element. // start the start position of the search (inclusive) // end the end position of the search (exclusive) func indexOf[T any](o T, e []T, start int, end int) int { if start >= end { return -1 } for i := start; i < end; i++ { if reflect.DeepEqual(e[i], o) { return i } } return -1 } // LastIndexOf returns the index of the last occurrence of the specified element in this list, or -1 if this list does not contain the element. func (c *CopyOnWriteList[T]) LastIndexOf(e T) int { list := c.getList() return lastIndexOf(e, list, 0, c.Size()) } // lastIndexOf returns the index of the last occurrence of the specified element in this list, or -1 if this list does not contain the element. // start the start position of the search (inclusive) // end the end position of the search (exclusive) func lastIndexOf[T any](o T, e []T, start int, end int) int { if start >= end { return -1 } for i := end - 1; i >= start; i-- { if reflect.DeepEqual(e[i], o) { return i } } return -1 } // LastIndexOfFunc returns the index of the last occurrence of the value in this list satisfying the // functional predicate f(T) bool // if not found return -1. func (l *CopyOnWriteList[T]) LastIndexOfFunc(f func(T) bool) int { index := -1 data := l.getList() for i := len(data) - 1; i >= 0; i-- { if f(data[i]) { index = i break } } return index } // IndexOfFunc returns the first index satisfying the functional predicate f(v) bool // if not found return -1. func (l *CopyOnWriteList[T]) IndexOfFunc(f func(T) bool) int { index := -1 data := l.getList() for i, v := range data { if f(v) { index = i break } } return index } // get returns the element at the specified position in this list. func get[T any](o []T, index int) *T { return &o[index] } // Get returns the element at the specified position in this list. func (c *CopyOnWriteList[T]) Get(index int) *T { list := c.getList() if index < 0 || index >= len(list) { return nil } return get(list, index) } func (c *CopyOnWriteList[T]) set(index int, e T) (oldValue *T) { lock := c.lock lock.Lock() defer lock.Unlock() list := c.getList() oldValue = get(list, index) if reflect.DeepEqual(oldValue, e) { c.setList(list) } else { newList := make([]T, len(list)) copy(newList, list) newList[index] = e c.setList(newList) } return } // Set replaces the element at the specified position in this list with the specified element. func (c *CopyOnWriteList[T]) Set(index int, e T) (oldValue *T, ok bool) { list := c.getList() if index < 0 || index >= len(list) { return oldValue, false } return c.set(index, e), true } // Add appends the specified element to the end of this list. func (c *CopyOnWriteList[T]) Add(e T) bool { lock := c.lock lock.Lock() defer lock.Unlock() list := c.getList() newList := make([]T, len(list)+1) copy(newList, list) newList[len(list)] = e c.setList(newList) return true } // AddAll appends all the elements in the specified collection to the end of this list func (c *CopyOnWriteList[T]) AddAll(e []T) bool { lock := c.lock lock.Lock() defer lock.Unlock() list := c.getList() newList := make([]T, len(list)+len(e)) copy(newList, list) copy(newList[len(list):], e) c.setList(newList) return true } // AddByIndex inserts the specified element at the specified position in this list. func (c *CopyOnWriteList[T]) AddByIndex(index int, e T) bool { lock := c.lock lock.Lock() defer lock.Unlock() list := c.getList() length := len(list) if index < 0 || index > length { return false } var newList []T var numMove = length - index if numMove == 0 { newList = make([]T, length+1) copy(newList, list) } else { newList = make([]T, length+1) copy(newList, list[:index]) copy(newList[index+1:], list[index:]) } newList[index] = e c.setList(newList) return true } // delete removes the element at the specified position in this list. func (c *CopyOnWriteList[T]) delete(index int) *T { lock := c.lock lock.Lock() defer lock.Unlock() list := c.getList() length := len(list) oldValue := get(list, index) numMove := length - index - 1 var newList []T if numMove == 0 { newList = make([]T, length-1) copy(newList, list[:index]) } else { newList = make([]T, length-1) copy(newList, list[:index]) copy(newList[index:], list[index+1:]) } c.setList(newList) return oldValue } // DeleteAt removes the element at the specified position in this list. func (c *CopyOnWriteList[T]) DeleteAt(index int) (*T, bool) { list := c.getList() if index < 0 || index >= len(list) { return nil, false } return c.delete(index), true } // DeleteBy removes the first occurrence of the specified element from this list, if it is present. func (c *CopyOnWriteList[T]) DeleteBy(o T) (*T, bool) { list := c.getList() index := indexOf(o, list, 0, len(list)) if index == -1 { return nil, false } return c.delete(index), true } // DeleteRange removes from this list all the elements whose index is between fromIndex, inclusive, and toIndex, exclusive. // left close and right open func (c *CopyOnWriteList[T]) DeleteRange(start int, end int) { lock := c.lock lock.Lock() defer lock.Unlock() list := c.getList() length := len(list) if start < 0 || end > length || start > end { return } var newList []T numMove := length - end if numMove == 0 { newList = make([]T, length-(end-start)) copy(newList, list[:start]) } else { newList = make([]T, length-(end-start)) copy(newList, list[:start]) copy(newList[start:], list[end:]) } c.setList(newList) } // DeleteIf removes all the elements of this collection that satisfy the given predicate. func (c *CopyOnWriteList[T]) DeleteIf(f func(T) bool) { lock := c.lock lock.Lock() defer lock.Unlock() list := c.getList() length := len(list) var newList []T for i := 0; i < length; i++ { if !f(list[i]) { newList = append(newList, list[i]) } } c.setList(newList) } // Equal returns true if the specified object is equal to this list. func (c *CopyOnWriteList[T]) Equal(other *[]T) bool { if other == nil { return false } if c.Size() != len(*other) { return false } list := c.getList() otherList := NewCopyOnWriteList(*other).getList() for i := 0; i < len(list); i++ { if !reflect.DeepEqual(list[i], otherList[i]) { return false } } return true } // Clear removes all the elements from this list. func (c *CopyOnWriteList[T]) Clear() { lock := c.lock lock.Lock() defer lock.Unlock() list := c.getList() list = make([]T, 0) c.setList(list) } // Merge a tow list to one, change the list func (c *CopyOnWriteList[T]) Merge(other []T) { lock := c.lock lock.Lock() defer lock.Unlock() list := c.getList() list = append(list, other...) c.setList(list) } // ForEach performs the given action for each element of the Iterable until all elements have been processed // or the action throws an exception. func (c *CopyOnWriteList[T]) ForEach(f func(T)) { list := c.getList() for i := 0; i < len(list); i++ { f(list[i]) } } // Sort sorts this list according to the order induced by the specified Comparator. func (c *CopyOnWriteList[T]) Sort(compare func(o1 T, o2 T) bool) { lock := c.lock lock.Lock() list := c.getList() sort.Slice(list, func(i, j int) bool { return compare(list[i], list[j]) }) c.setList(list) } func (c *CopyOnWriteList[T]) SubList(start int, end int) (newList []T) { lock := c.lock lock.Lock() list := c.getList() length := len(list) defer lock.Unlock() if start < 0 || end > length || start > end { return []T{} } newList = make([]T, end-start) copy(newList, list[start:end]) c.setList(newList) return }