github.com/tursom/GoCollections@v0.3.10/collections/LinkedList.go (about)

     1  /*
     2   * Copyright (c) 2022 tursom. All rights reserved.
     3   * Use of this source code is governed by a GPL-3
     4   * license that can be found in the LICENSE file.
     5   */
     6  
     7  package collections
     8  
     9  import (
    10  	"github.com/tursom/GoCollections/exceptions"
    11  	"github.com/tursom/GoCollections/lang"
    12  )
    13  
    14  type (
    15  	LinkedList[T lang.Object] struct {
    16  		lang.BaseObject
    17  		head *linkedListNode[T]
    18  		size int
    19  	}
    20  	linkedListNode[T lang.Object] struct {
    21  		prev, next *linkedListNode[T]
    22  		value      T
    23  	}
    24  	linkedListIterator[T lang.Object] struct {
    25  		list       *LinkedList[T]
    26  		node, head *linkedListNode[T]
    27  		index      int
    28  	}
    29  )
    30  
    31  func (l *LinkedList[T]) String() string {
    32  	return String[T](l)
    33  }
    34  
    35  func NewLinkedList[T lang.Object]() *LinkedList[T] {
    36  	tail := &linkedListNode[T]{}
    37  	tail.prev = tail
    38  	tail.next = tail
    39  	return &LinkedList[T]{lang.NewBaseObject(), tail, 0}
    40  }
    41  
    42  func NewLinkedListFrom[T lang.Object](list List[T], from, to int) *LinkedList[T] {
    43  	newList := NewLinkedList[T]()
    44  	iterator, err := SkipIterator[T](list.ListIterator(), to-from)
    45  	if err != nil {
    46  		panic(err)
    47  	}
    48  
    49  	for i := 0; i < to-from; i++ {
    50  		next, err := iterator.Next()
    51  		if err != nil {
    52  			panic(err)
    53  		}
    54  
    55  		// newList wont throw any exception in this place
    56  		_ = newList.Add(next)
    57  	}
    58  
    59  	return newList
    60  }
    61  
    62  func (l *LinkedList[T]) Size() int {
    63  	return l.size
    64  }
    65  
    66  func (l *LinkedList[T]) IsEmpty() bool {
    67  	return l.size == 0
    68  }
    69  
    70  func (l *LinkedList[T]) Contains(element T) bool {
    71  	return Contains[T](l, element)
    72  }
    73  
    74  func (l *LinkedList[T]) ContainsAll(c Collection[T]) bool {
    75  	return ContainsAll[T](l, c)
    76  }
    77  
    78  func (l *LinkedList[T]) Add(element T) bool {
    79  	l.size++
    80  	node := &linkedListNode[T]{l.head.prev, l.head, element}
    81  	node.next.prev = node
    82  	node.prev.next = node
    83  	return true
    84  }
    85  
    86  func (l *LinkedList[T]) Remove(element T) exceptions.Exception {
    87  	err := LoopMutable[T](l, func(e T, iterator MutableIterator[T]) exceptions.Exception {
    88  		if lang.Equals(element, e) {
    89  			iterator.Remove()
    90  			return exceptions.CollectionLoopFinished
    91  		}
    92  		return nil
    93  	})
    94  	if err != nil {
    95  		return nil
    96  	} else {
    97  		return exceptions.NewElementNotFoundException("", nil)
    98  	}
    99  }
   100  
   101  func (l *LinkedList[T]) AddAll(c Collection[T]) bool {
   102  	return AddAll[T](l, c)
   103  }
   104  
   105  func (l *LinkedList[T]) RemoveAll(c Collection[T]) bool {
   106  	return RemoveAll[T](l, c)
   107  }
   108  
   109  func (l *LinkedList[T]) RetainAll(c Collection[T]) bool {
   110  	return RetainAll[T](l, c)
   111  }
   112  
   113  func (l *LinkedList[T]) Clear() {
   114  	l.head.next = l.head
   115  	l.size = 0
   116  }
   117  
   118  func (l *LinkedList[T]) SubList(from, to int) List[T] {
   119  	return l.SubMutableList(from, to)
   120  }
   121  
   122  func (l *LinkedList[T]) Set(index int, element T) exceptions.Exception {
   123  	node := l.head
   124  	for node != l.head {
   125  		if index == 0 {
   126  			node.value = element
   127  			return nil
   128  		}
   129  		index--
   130  	}
   131  	return exceptions.NewIndexOutOfBound("", nil)
   132  }
   133  
   134  func (l *LinkedList[T]) AddAtIndex(index int, element T) bool {
   135  	node := l.head
   136  	for node != l.head {
   137  		if index == 0 {
   138  			l.size++
   139  			node.next = &linkedListNode[T]{node, node.next, element}
   140  			node.next.next.prev = node.next
   141  			return true
   142  		}
   143  		index--
   144  	}
   145  	return false
   146  }
   147  
   148  func (l *LinkedList[T]) addAtNode(node *linkedListNode[T], element T) {
   149  	l.size++
   150  	node.next = &linkedListNode[T]{node, node.next, element}
   151  	node.next.next.prev = node.next
   152  }
   153  
   154  func (l *LinkedList[T]) RemoveAt(index int) exceptions.Exception {
   155  	node := l.head
   156  	for node != l.head {
   157  		if index == 0 {
   158  			l.size--
   159  			node.remove()
   160  			return nil
   161  		}
   162  		index--
   163  	}
   164  	return exceptions.NewIndexOutOfBound("", nil)
   165  }
   166  func (l *LinkedList[T]) RemoveLast() (T, exceptions.Exception) {
   167  	if l.head.next == l.head {
   168  		return lang.Nil[T](), exceptions.NewIndexOutOfBound("list is empty", nil)
   169  	}
   170  	return l.head.prev.remove(), nil
   171  }
   172  
   173  func (l *LinkedList[T]) SubMutableList(from, to int) MutableList[T] {
   174  	if from < 0 || from < to || to > l.size {
   175  		panic(exceptions.NewIndexOutOfBound("", nil))
   176  	}
   177  	list := NewLinkedList[T]()
   178  	if from == to {
   179  		return list
   180  	}
   181  	node := l.head
   182  	for i := 0; i < from; i++ {
   183  		node = node.next
   184  	}
   185  	for i := from; i < to; i++ {
   186  		node = node.next
   187  		list.Add(node.value)
   188  	}
   189  	return list
   190  	return NewArrayListFrom[T](l, from, to)
   191  }
   192  
   193  func (l *LinkedList[T]) Get(index int) (T, exceptions.Exception) {
   194  	if index < l.size/2 {
   195  		return loopLinkedListNodeUp[T](l.head, index)
   196  	} else {
   197  		return loopLinkedListNodeDown[T](l.head, l.size-index-1)
   198  	}
   199  }
   200  
   201  func loopLinkedListNodeUp[T lang.Object](head *linkedListNode[T], index int) (T, exceptions.Exception) {
   202  	node := head.next
   203  	for node != head {
   204  		if index == 0 {
   205  			return node.value, nil
   206  		}
   207  		index--
   208  		node = node.next
   209  	}
   210  
   211  	return lang.Nil[T](), exceptions.NewIndexOutOfBound("", nil)
   212  }
   213  
   214  func loopLinkedListNodeDown[T lang.Object](head *linkedListNode[T], index int) (T, exceptions.Exception) {
   215  	node := head.prev
   216  	for node != head {
   217  		if index == 0 {
   218  			return node.value, nil
   219  		}
   220  		index--
   221  		node = node.prev
   222  	}
   223  
   224  	return lang.Nil[T](), exceptions.NewIndexOutOfBound("", nil)
   225  }
   226  
   227  func (l *LinkedList[T]) Iterator() Iterator[T] {
   228  	return l.MutableIterator()
   229  }
   230  
   231  func (l *LinkedList[T]) MutableIterator() MutableIterator[T] {
   232  	return l.MutableListIterator()
   233  }
   234  
   235  func (l *LinkedList[T]) ListIterator() ListIterator[T] {
   236  	return l.MutableListIterator()
   237  }
   238  
   239  func (l *LinkedList[T]) MutableListIterator() MutableListIterator[T] {
   240  	return &linkedListIterator[T]{l, l.head.next, l.head, 0}
   241  }
   242  
   243  func (l *linkedListIterator[T]) HasNext() bool {
   244  	return l.node != l.head
   245  }
   246  
   247  func (l *linkedListIterator[T]) Next() (T, exceptions.Exception) {
   248  	if l.node == l.head {
   249  		return lang.Nil[T](), exceptions.NewIndexOutOfBound("", nil)
   250  	}
   251  	l.node = l.node.next
   252  	l.index++
   253  	return l.node.prev.value, nil
   254  }
   255  
   256  func (l *linkedListIterator[T]) Remove() exceptions.Exception {
   257  	if l.node.prev == l.head {
   258  		return exceptions.NewIndexOutOfBound("", nil)
   259  	}
   260  	l.node.prev.remove()
   261  	l.list.size--
   262  	return nil
   263  }
   264  
   265  func (l *linkedListNode[T]) remove() T {
   266  	l.next.prev = l.prev
   267  	l.prev.next = l.next
   268  	return l.value
   269  }
   270  
   271  func (l *linkedListIterator[T]) HasPrevious() bool {
   272  	return l.head.next != l.head
   273  }
   274  
   275  func (l *linkedListIterator[T]) Previous() (T, exceptions.Exception) {
   276  	if l.node.prev.prev == l.head {
   277  		return lang.Nil[T](), exceptions.NewIndexOutOfBound("", nil)
   278  	}
   279  	l.node = l.node.prev
   280  	l.index--
   281  	return l.node.prev.value, nil
   282  }
   283  
   284  func (l *linkedListIterator[T]) NextIndex() int {
   285  	return l.index
   286  }
   287  
   288  func (l *linkedListIterator[T]) PreviousIndex() int {
   289  	return l.index - 1
   290  }
   291  
   292  func (l *linkedListIterator[T]) Set(value T) exceptions.Exception {
   293  	l.node.prev.value = value
   294  	return nil
   295  }
   296  
   297  func (l *linkedListIterator[T]) Add(value T) exceptions.Exception {
   298  	l.list.addAtNode(l.node.prev, value)
   299  	return nil
   300  }