GoCollections/collections/LinkedList.go

182 lines
3.4 KiB
Go
Raw Normal View History

2021-05-20 17:32:35 +08:00
package collections
import (
2021-05-21 09:48:33 +08:00
"github.com/tursom/GoCollections/exceptions"
2021-05-20 17:32:35 +08:00
)
type (
LinkedList struct {
head *linkedListNode
size uint32
}
linkedListNode struct {
prev, next *linkedListNode
value interface{}
}
)
func (l LinkedList) String() string {
return String(l)
}
func NewLinkedList() *LinkedList {
tail := &linkedListNode{}
tail.prev = tail
tail.next = tail
return &LinkedList{tail, 0}
}
func (l LinkedList) Size() uint32 {
return l.size
}
func (l LinkedList) IsEmpty() bool {
return l.size == 0
}
func (l LinkedList) Contains(element interface{}) bool {
return Contains(&l, element)
}
func (l LinkedList) ContainsAll(c Collection) bool {
return ContainsAll(&l, c)
}
func (l *LinkedList) Add(element interface{}) bool {
l.size++
node := &linkedListNode{l.head.prev, l.head, element}
node.next.prev = node
node.prev.next = node
return true
}
2021-05-21 09:41:58 +08:00
func (l *LinkedList) Remove(element interface{}) error {
err := LoopMutable(l, func(e interface{}, iterator MutableIterator) error {
2021-05-20 17:32:35 +08:00
if element == e {
iterator.Remove()
return exceptions.CollectionLoopFinished
}
return nil
2021-05-21 09:41:58 +08:00
})
if err != nil {
return nil
} else {
return exceptions.NewElementNotFoundException("", true)
}
2021-05-20 17:32:35 +08:00
}
func (l *LinkedList) AddAll(c Collection) bool {
return AddAll(l, c)
}
func (l *LinkedList) RemoveAll(c Collection) bool {
return RemoveAll(l, c)
}
func (l *LinkedList) RetainAll(c Collection) bool {
return RetainAll(l, c)
}
func (l *LinkedList) Clear() {
l.head.next = l.head
l.size = 0
}
func (l LinkedList) SubList(from, to uint32) List {
return NewSubList(l, from, to)
}
2021-05-21 09:41:58 +08:00
func (l *LinkedList) Set(index uint32, element interface{}) error {
2021-05-20 17:32:35 +08:00
node := l.head
for node != l.head {
if index == 0 {
node.value = element
2021-05-21 09:41:58 +08:00
return nil
2021-05-20 17:32:35 +08:00
}
index--
}
2021-05-21 09:41:58 +08:00
return exceptions.NewIndexOutOfBound("", true)
2021-05-20 17:32:35 +08:00
}
func (l *LinkedList) AddAtIndex(index uint32, element interface{}) bool {
node := l.head
for node != l.head {
if index == 0 {
l.size++
node.next = &linkedListNode{node, node.next, element}
node.next.next.prev = node.next
return true
}
index--
}
return false
}
2021-05-21 10:31:49 +08:00
func (l *LinkedList) RemoveAt(index uint32) error {
2021-05-20 17:32:35 +08:00
node := l.head
for node != l.head {
if index == 0 {
l.size--
node.remove()
2021-05-21 10:31:49 +08:00
return nil
2021-05-20 17:32:35 +08:00
}
index--
}
2021-05-21 10:31:49 +08:00
return exceptions.NewIndexOutOfBound("", true)
2021-05-20 17:32:35 +08:00
}
func (l *LinkedList) SubMutableList(from, to uint32) MutableList {
return NewMutableSubList(l, from, to)
}
func (l LinkedList) Get(index uint32) (interface{}, error) {
node := l.head
for node != l.head {
if index == 0 {
return node.value, nil
}
index--
}
return nil, exceptions.NewIndexOutOfBound("", true)
}
func (l LinkedList) Iterator() Iterator {
return l.MutableIterator()
}
func (l *LinkedList) MutableIterator() MutableIterator {
return &linkedListIterator{l, l.head.next, l.head}
}
type linkedListIterator struct {
list *LinkedList
node, head *linkedListNode
}
func (l *linkedListIterator) HasNext() bool {
return l.node != l.head
}
2021-05-21 09:41:58 +08:00
func (l *linkedListIterator) Next() (interface{}, error) {
2021-05-20 17:32:35 +08:00
if l.node == l.head {
2021-05-21 09:41:58 +08:00
return nil, exceptions.NewIndexOutOfBound("", true)
2021-05-20 17:32:35 +08:00
}
l.node = l.node.next
2021-05-21 09:41:58 +08:00
return l.node.prev.value, nil
2021-05-20 17:32:35 +08:00
}
2021-05-21 10:31:49 +08:00
func (l *linkedListIterator) Remove() error {
2021-05-20 17:32:35 +08:00
if l.node.prev == l.head {
2021-05-21 10:31:49 +08:00
return exceptions.NewIndexOutOfBound("", true)
2021-05-20 17:32:35 +08:00
}
l.node.prev.remove()
l.list.size--
2021-05-21 10:31:49 +08:00
return nil
2021-05-20 17:32:35 +08:00
}
func (l *linkedListNode) remove() {
l.next.prev = l.prev
l.prev.next = l.next
}