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 }