gitee.com/quant1x/gox@v1.21.2/util/arraylist/arraylist.go (about)

     1  // Copyright (c) 2015, Emir Pasic. 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 arraylist implements the array list.
     6  //
     7  // Structure is not thread safe.
     8  //
     9  // Reference: https://en.wikipedia.org/wiki/List_%28abstract_data_type%29
    10  package arraylist
    11  
    12  import (
    13  	"fmt"
    14  	"gitee.com/quant1x/gox/util/internal"
    15  	"strings"
    16  )
    17  
    18  func assertListImplementation() {
    19  	var _ internal.List = (*List)(nil)
    20  }
    21  
    22  // List holds the elements in a slice
    23  type List struct {
    24  	elements []interface{}
    25  	size     int
    26  }
    27  
    28  const (
    29  	growthFactor = float32(2.0)  // growth by 100%
    30  	shrinkFactor = float32(0.25) // shrink when size is 25% of capacity (0 means never shrink)
    31  )
    32  
    33  // New instantiates a new list and adds the passed values, if any, to the list
    34  func New(values ...interface{}) *List {
    35  	list := &List{}
    36  	if len(values) > 0 {
    37  		list.Add(values...)
    38  	}
    39  	return list
    40  }
    41  
    42  // Add appends a value at the end of the list
    43  func (list *List) Add(values ...interface{}) {
    44  	list.growBy(len(values))
    45  	for _, value := range values {
    46  		list.elements[list.size] = value
    47  		list.size++
    48  	}
    49  }
    50  
    51  // Get returns the element at index.
    52  // Second return parameter is true if index is within bounds of the array and array is not empty, otherwise false.
    53  func (list *List) Get(index int) (interface{}, bool) {
    54  
    55  	if !list.withinRange(index) {
    56  		return nil, false
    57  	}
    58  
    59  	return list.elements[index], true
    60  }
    61  
    62  // Remove removes the element at the given index from the list.
    63  func (list *List) Remove(index int) {
    64  
    65  	if !list.withinRange(index) {
    66  		return
    67  	}
    68  
    69  	list.elements[index] = nil                                    // cleanup reference
    70  	copy(list.elements[index:], list.elements[index+1:list.size]) // shift to the left by one (slow operation, need ways to optimize this)
    71  	list.size--
    72  
    73  	list.shrink()
    74  }
    75  
    76  // Contains checks if elements (one or more) are present in the set.
    77  // All elements have to be present in the set for the method to return true.
    78  // Performance time complexity of n^2.
    79  // Returns true if no arguments are passed at all, i.e. set is always super-set of empty set.
    80  func (list *List) Contains(values ...interface{}) bool {
    81  
    82  	for _, searchValue := range values {
    83  		found := false
    84  		for _, element := range list.elements {
    85  			if element == searchValue {
    86  				found = true
    87  				break
    88  			}
    89  		}
    90  		if !found {
    91  			return false
    92  		}
    93  	}
    94  	return true
    95  }
    96  
    97  // Values returns all elements in the list.
    98  func (list *List) Values() []interface{} {
    99  	newElements := make([]interface{}, list.size, list.size)
   100  	copy(newElements, list.elements[:list.size])
   101  	return newElements
   102  }
   103  
   104  // IndexOf returns index of provided element
   105  func (list *List) IndexOf(value interface{}) int {
   106  	if list.size == 0 {
   107  		return -1
   108  	}
   109  	for index, element := range list.elements {
   110  		if element == value {
   111  			return index
   112  		}
   113  	}
   114  	return -1
   115  }
   116  
   117  // Empty returns true if list does not contain any elements.
   118  func (list *List) Empty() bool {
   119  	return list.size == 0
   120  }
   121  
   122  // Size returns number of elements within the list.
   123  func (list *List) Size() int {
   124  	return list.size
   125  }
   126  
   127  // Clear removes all elements from the list.
   128  func (list *List) Clear() {
   129  	list.size = 0
   130  	list.elements = []interface{}{}
   131  }
   132  
   133  // Sort sorts values (in-place) using.
   134  func (list *List) Sort(comparator internal.Comparator) {
   135  	if len(list.elements) < 2 {
   136  		return
   137  	}
   138  	internal.Sort(list.elements[:list.size], comparator)
   139  }
   140  
   141  // Swap swaps the two values at the specified positions.
   142  func (list *List) Swap(i, j int) {
   143  	if list.withinRange(i) && list.withinRange(j) {
   144  		list.elements[i], list.elements[j] = list.elements[j], list.elements[i]
   145  	}
   146  }
   147  
   148  // Insert inserts values at specified index position shifting the value at that position (if any) and any subsequent elements to the right.
   149  // Does not do anything if position is negative or bigger than list's size
   150  // Note: position equal to list's size is valid, i.e. append.
   151  func (list *List) Insert(index int, values ...interface{}) {
   152  
   153  	if !list.withinRange(index) {
   154  		// Append
   155  		if index == list.size {
   156  			list.Add(values...)
   157  		}
   158  		return
   159  	}
   160  
   161  	l := len(values)
   162  	list.growBy(l)
   163  	list.size += l
   164  	copy(list.elements[index+l:], list.elements[index:list.size-l])
   165  	copy(list.elements[index:], values)
   166  }
   167  
   168  // Set the value at specified index
   169  // Does not do anything if position is negative or bigger than list's size
   170  // Note: position equal to list's size is valid, i.e. append.
   171  func (list *List) Set(index int, value interface{}) {
   172  
   173  	if !list.withinRange(index) {
   174  		// Append
   175  		if index == list.size {
   176  			list.Add(value)
   177  		}
   178  		return
   179  	}
   180  
   181  	list.elements[index] = value
   182  }
   183  
   184  // String returns a string representation of container
   185  func (list *List) String() string {
   186  	str := "ArrayList\n"
   187  	values := []string{}
   188  	for _, value := range list.elements[:list.size] {
   189  		values = append(values, fmt.Sprintf("%v", value))
   190  	}
   191  	str += strings.Join(values, ", ")
   192  	return str
   193  }
   194  
   195  // Check that the index is within bounds of the list
   196  func (list *List) withinRange(index int) bool {
   197  	return index >= 0 && index < list.size
   198  }
   199  
   200  func (list *List) resize(cap int) {
   201  	newElements := make([]interface{}, cap, cap)
   202  	copy(newElements, list.elements)
   203  	list.elements = newElements
   204  }
   205  
   206  // Expand the array if necessary, i.e. capacity will be reached if we add n elements
   207  func (list *List) growBy(n int) {
   208  	// When capacity is reached, grow by a factor of growthFactor and add number of elements
   209  	currentCapacity := cap(list.elements)
   210  	if list.size+n >= currentCapacity {
   211  		newCapacity := int(growthFactor * float32(currentCapacity+n))
   212  		list.resize(newCapacity)
   213  	}
   214  }
   215  
   216  // Shrink the array if necessary, i.e. when size is shrinkFactor percent of current capacity
   217  func (list *List) shrink() {
   218  	if shrinkFactor == 0.0 {
   219  		return
   220  	}
   221  	// Shrink when size is at shrinkFactor * capacity
   222  	currentCapacity := cap(list.elements)
   223  	if list.size <= int(float32(currentCapacity)*shrinkFactor) {
   224  		list.resize(list.size)
   225  	}
   226  }