mirror of
https://github.com/tursom/GoCollections.git
synced 2025-03-13 17:00:18 +08:00
update
This commit is contained in:
parent
8fe538eb7e
commit
0c0db78b2f
@ -27,27 +27,35 @@ func NewArrayListByCapacity[T lang.Object](cap int) *ArrayList[T] {
|
||||
}
|
||||
}
|
||||
|
||||
func (a ArrayList[T]) String() string {
|
||||
func (a *ArrayList[T]) String() string {
|
||||
return String[T](a)
|
||||
}
|
||||
|
||||
func (a ArrayList[T]) Iterator() Iterator[T] {
|
||||
func (a *ArrayList[T]) Iterator() Iterator[T] {
|
||||
return a.MutableIterator()
|
||||
}
|
||||
|
||||
func (a ArrayList[T]) Size() int {
|
||||
func (a *ArrayList[T]) ListIterator() ListIterator[T] {
|
||||
return a.MutableListIterator()
|
||||
}
|
||||
|
||||
func (a *ArrayList[T]) MutableListIterator() MutableListIterator[T] {
|
||||
return &arrayListIterator[T]{a, 0}
|
||||
}
|
||||
|
||||
func (a *ArrayList[T]) Size() int {
|
||||
return lang.Len(a.array)
|
||||
}
|
||||
|
||||
func (a ArrayList[T]) IsEmpty() bool {
|
||||
func (a *ArrayList[T]) IsEmpty() bool {
|
||||
return a.Size() == 0
|
||||
}
|
||||
|
||||
func (a ArrayList[T]) Contains(element T) bool {
|
||||
func (a *ArrayList[T]) Contains(element T) bool {
|
||||
return Contains[T](a, element)
|
||||
}
|
||||
|
||||
func (a ArrayList[T]) ContainsAll(c Collection[T]) bool {
|
||||
func (a *ArrayList[T]) ContainsAll(c Collection[T]) bool {
|
||||
return ContainsAll[T](a, c)
|
||||
}
|
||||
|
||||
@ -56,7 +64,7 @@ func (a *ArrayList[T]) Add(element T) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (a ArrayList[T]) IndexOf(element T) int {
|
||||
func (a *ArrayList[T]) IndexOf(element T) int {
|
||||
for i := 0; i < a.Size(); i++ {
|
||||
if lang.Equals(element, a.array[i]) {
|
||||
return i
|
||||
@ -90,7 +98,7 @@ func (a *ArrayList[T]) Clear() {
|
||||
a.array = []T{}
|
||||
}
|
||||
|
||||
func (a ArrayList[T]) Get(index int) (T, exceptions.Exception) {
|
||||
func (a *ArrayList[T]) Get(index int) (T, exceptions.Exception) {
|
||||
if index >= a.Size() {
|
||||
return lang.Nil[T](), exceptions.NewIndexOutOfBound("", nil)
|
||||
} else {
|
||||
@ -98,8 +106,8 @@ func (a ArrayList[T]) Get(index int) (T, exceptions.Exception) {
|
||||
}
|
||||
}
|
||||
|
||||
func (a ArrayList[T]) SubList(from, to int) List[T] {
|
||||
return NewSubList[T](a, from, to)
|
||||
func (a *ArrayList[T]) SubList(from, to int) List[T] {
|
||||
return a.SubMutableList(from, to)
|
||||
}
|
||||
|
||||
func (a *ArrayList[T]) Set(index int, element T) exceptions.Exception {
|
||||
@ -131,7 +139,9 @@ func (a *ArrayList[T]) RemoveAt(index int) exceptions.Exception {
|
||||
}
|
||||
|
||||
func (a *ArrayList[T]) SubMutableList(from, to int) MutableList[T] {
|
||||
return NewMutableSubList[T](a, from, to)
|
||||
return &ArrayList[T]{
|
||||
array: a.array[from:to],
|
||||
}
|
||||
}
|
||||
|
||||
func (a *ArrayList[T]) MutableIterator() MutableIterator[T] {
|
||||
@ -164,3 +174,37 @@ func (a *arrayListIterator[T]) Remove() exceptions.Exception {
|
||||
a.index--
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *arrayListIterator[T]) HasPrevious() bool {
|
||||
return a.index > 0
|
||||
}
|
||||
|
||||
func (a *arrayListIterator[T]) Previous() (T, exceptions.Exception) {
|
||||
if a.index <= 0 || a.index >= len(a.arrayList.array) {
|
||||
return lang.Nil[T](), exceptions.NewIndexOutOfBound("", nil)
|
||||
}
|
||||
a.index--
|
||||
return a.arrayList.array[a.index], a.arrayList.RemoveAt(a.index)
|
||||
}
|
||||
|
||||
func (a *arrayListIterator[T]) NextIndex() int {
|
||||
return a.index
|
||||
}
|
||||
|
||||
func (a *arrayListIterator[T]) PreviousIndex() int {
|
||||
return a.index - 1
|
||||
}
|
||||
|
||||
func (a *arrayListIterator[T]) Set(value T) exceptions.Exception {
|
||||
if a.index <= 0 {
|
||||
return exceptions.NewIndexOutOfBound("", nil)
|
||||
}
|
||||
a.arrayList.array[a.index-1] = value
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *arrayListIterator[T]) Add(value T) exceptions.Exception {
|
||||
a.arrayList.AddAtIndex(a.index, value)
|
||||
a.index++
|
||||
return nil
|
||||
}
|
||||
|
@ -2,18 +2,19 @@ package collections
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/tursom/GoCollections/exceptions"
|
||||
"github.com/tursom/GoCollections/lang"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type (
|
||||
Collection[T any] interface {
|
||||
Iterable[T]
|
||||
Collection[E any] interface {
|
||||
Iterable[E]
|
||||
Size() int
|
||||
IsEmpty() bool
|
||||
Contains(element T) bool
|
||||
ContainsAll(c Collection[T]) bool
|
||||
Contains(element E) bool
|
||||
ContainsAll(c Collection[E]) bool
|
||||
}
|
||||
|
||||
MutableCollection[T any] interface {
|
||||
@ -33,6 +34,7 @@ type (
|
||||
|
||||
Get(index int) (T, exceptions.Exception)
|
||||
SubList(from, to int) List[T]
|
||||
ListIterator() ListIterator[T]
|
||||
}
|
||||
|
||||
MutableList[T any] interface {
|
||||
@ -43,6 +45,7 @@ type (
|
||||
AddAtIndex(index int, element T) bool
|
||||
RemoveAt(index int) exceptions.Exception
|
||||
SubMutableList(from, to int) MutableList[T]
|
||||
MutableListIterator() MutableListIterator[T]
|
||||
}
|
||||
)
|
||||
|
||||
|
@ -1,168 +0,0 @@
|
||||
package collections
|
||||
|
||||
import (
|
||||
"github.com/tursom/GoCollections/exceptions"
|
||||
"github.com/tursom/GoCollections/lang"
|
||||
"github.com/tursom/GoCollections/lang/atomic"
|
||||
)
|
||||
|
||||
type (
|
||||
ConcurrentLinkedQueueNode[T lang.Object] interface {
|
||||
Get() (T, exceptions.Exception)
|
||||
Remove() exceptions.Exception
|
||||
RemoveAndGet() (T, exceptions.Exception)
|
||||
}
|
||||
|
||||
ConcurrentLinkedQueue[T lang.Object] struct {
|
||||
lang.BaseObject
|
||||
ConcurrentLinkedStack[T]
|
||||
end *concurrentLinkedStackNode[T]
|
||||
}
|
||||
|
||||
concurrentLinkedQueueIterator[T lang.Object] struct {
|
||||
node *concurrentLinkedStackNode[T]
|
||||
queue *ConcurrentLinkedQueue[T]
|
||||
}
|
||||
)
|
||||
|
||||
func (q *ConcurrentLinkedQueue[T]) String() string {
|
||||
return String[T](q)
|
||||
}
|
||||
|
||||
func NewConcurrentLinkedQueue[T lang.Object]() *ConcurrentLinkedQueue[T] {
|
||||
return &ConcurrentLinkedQueue[T]{}
|
||||
}
|
||||
|
||||
func (q *ConcurrentLinkedQueue[T]) Iterator() Iterator[T] {
|
||||
return q.MutableIterator()
|
||||
}
|
||||
|
||||
func (q *ConcurrentLinkedQueue[T]) Offer(element T) exceptions.Exception {
|
||||
_, err := q.offerAndGetNode(element)
|
||||
return err
|
||||
}
|
||||
|
||||
func (q *ConcurrentLinkedQueue[T]) OfferAndGetNode(element T) (ConcurrentLinkedQueueNode[T], exceptions.Exception) {
|
||||
newNode, err := q.offerAndGetNode(element)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &concurrentLinkedQueueIterator[T]{queue: q, node: newNode}, nil
|
||||
}
|
||||
|
||||
func (q *ConcurrentLinkedQueue[T]) offerAndGetNode(element T) (*concurrentLinkedStackNode[T], exceptions.Exception) {
|
||||
newNode := &concurrentLinkedStackNode[T]{value: element}
|
||||
q.size.Add(1)
|
||||
|
||||
var next **concurrentLinkedStackNode[T]
|
||||
ref := q.end
|
||||
switch {
|
||||
case ref == nil:
|
||||
next = &q.head
|
||||
default:
|
||||
next = &ref.next
|
||||
}
|
||||
for !atomic.CompareAndSwapPointer(next, nil, newNode) {
|
||||
if ref == nil || ref.next == nil {
|
||||
next = &q.head
|
||||
ref = q.head
|
||||
} else {
|
||||
for ref.next != nil {
|
||||
ref = ref.next
|
||||
}
|
||||
next = &ref.next
|
||||
}
|
||||
}
|
||||
q.end = newNode
|
||||
return newNode, nil
|
||||
}
|
||||
|
||||
func (q *ConcurrentLinkedQueue[T]) Poll() (T, exceptions.Exception) {
|
||||
return q.Pop()
|
||||
}
|
||||
|
||||
func (q *ConcurrentLinkedQueue[T]) MutableIterator() MutableIterator[T] {
|
||||
return &concurrentLinkedQueueIterator[T]{queue: q, node: q.head}
|
||||
}
|
||||
|
||||
func (q *ConcurrentLinkedQueue[T]) Size() int {
|
||||
return int(q.size.Load())
|
||||
}
|
||||
|
||||
func (q *ConcurrentLinkedQueue[T]) IsEmpty() bool {
|
||||
return q.head == nil
|
||||
}
|
||||
|
||||
func (q *ConcurrentLinkedQueue[T]) Contains(element T) bool {
|
||||
return Contains[T](q, element)
|
||||
}
|
||||
|
||||
func (q *ConcurrentLinkedQueue[T]) ContainsAll(collection Collection[T]) bool {
|
||||
return ContainsAll[T](q, collection)
|
||||
}
|
||||
|
||||
func (q *ConcurrentLinkedQueue[T]) Add(element T) bool {
|
||||
exception := q.Push(element)
|
||||
exceptions.Print(exception)
|
||||
return exception == nil
|
||||
}
|
||||
|
||||
func (q *ConcurrentLinkedQueue[T]) Remove(element T) exceptions.Exception {
|
||||
return Remove[T](q, element)
|
||||
}
|
||||
|
||||
func (q *ConcurrentLinkedQueue[T]) AddAll(collection Collection[T]) bool {
|
||||
return AddAll[T](q, collection)
|
||||
}
|
||||
|
||||
func (q *ConcurrentLinkedQueue[T]) RemoveAll(collection Collection[T]) bool {
|
||||
return RemoveAll[T](q, collection)
|
||||
}
|
||||
|
||||
func (q *ConcurrentLinkedQueue[T]) RetainAll(collection Collection[T]) bool {
|
||||
return RetainAll[T](q, collection)
|
||||
}
|
||||
|
||||
func (q *ConcurrentLinkedQueue[T]) Clear() {
|
||||
q.head = nil
|
||||
q.end = nil
|
||||
q.size.Store(0)
|
||||
}
|
||||
|
||||
func (i *concurrentLinkedQueueIterator[T]) HasNext() bool {
|
||||
for i.node != nil && i.node.deleted {
|
||||
i.node = i.node.next
|
||||
}
|
||||
return i.node != nil
|
||||
}
|
||||
|
||||
func (i *concurrentLinkedQueueIterator[T]) Next() (T, exceptions.Exception) {
|
||||
value, err := i.Get()
|
||||
i.node = i.node.next
|
||||
for i.node != nil && i.node.deleted {
|
||||
i.node = i.node.next
|
||||
}
|
||||
return value, err
|
||||
}
|
||||
|
||||
func (i *concurrentLinkedQueueIterator[T]) Get() (T, exceptions.Exception) {
|
||||
return (*i.node).value, nil
|
||||
}
|
||||
|
||||
func (i *concurrentLinkedQueueIterator[T]) Remove() exceptions.Exception {
|
||||
_, err := i.RemoveAndGet()
|
||||
return err
|
||||
}
|
||||
|
||||
func (i *concurrentLinkedQueueIterator[T]) RemoveAndGet() (T, exceptions.Exception) {
|
||||
if i.node == nil {
|
||||
return lang.Nil[T](), nil
|
||||
}
|
||||
load := i.node
|
||||
load.deleted = true
|
||||
i.queue.size.Add(-1)
|
||||
i.queue.deleted.Add(1)
|
||||
i.queue.CleanDeleted()
|
||||
i.node = load.next
|
||||
return load.value, nil
|
||||
}
|
@ -1,148 +0,0 @@
|
||||
package collections
|
||||
|
||||
import (
|
||||
"github.com/tursom/GoCollections/exceptions"
|
||||
"github.com/tursom/GoCollections/lang"
|
||||
"github.com/tursom/GoCollections/lang/atomic"
|
||||
)
|
||||
|
||||
type (
|
||||
ConcurrentLinkedStack[T lang.Object] struct {
|
||||
lang.BaseObject
|
||||
size atomic.Int32
|
||||
deleted atomic.Int32
|
||||
head *concurrentLinkedStackNode[T]
|
||||
}
|
||||
|
||||
concurrentLinkedStackNode[T any] struct {
|
||||
deleted bool
|
||||
next *concurrentLinkedStackNode[T]
|
||||
value T
|
||||
}
|
||||
|
||||
concurrentLinkedStackIterator[T lang.Object] struct {
|
||||
node *concurrentLinkedStackNode[T]
|
||||
stack *ConcurrentLinkedStack[T]
|
||||
}
|
||||
)
|
||||
|
||||
func (s *ConcurrentLinkedStack[T]) String() string {
|
||||
return String[T](s)
|
||||
}
|
||||
|
||||
func NewConcurrentLinkedStack[T lang.Object]() *ConcurrentLinkedStack[T] {
|
||||
return &ConcurrentLinkedStack[T]{}
|
||||
}
|
||||
|
||||
func (s *ConcurrentLinkedStack[T]) Iterator() Iterator[T] {
|
||||
return s.MutableIterator()
|
||||
}
|
||||
|
||||
func (s *ConcurrentLinkedStack[T]) Push(element T) exceptions.Exception {
|
||||
newNode := &concurrentLinkedStackNode[T]{value: element, next: s.head}
|
||||
for !atomic.CompareAndSwapPointer(&s.head, newNode.next, newNode) {
|
||||
newNode.next = s.head
|
||||
}
|
||||
s.size.Add(1)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *ConcurrentLinkedStack[T]) Pop() (T, exceptions.Exception) {
|
||||
node := s.head
|
||||
for node != nil && (!atomic.CompareAndSwapPointer(&s.head, node, node.next) || node.deleted) {
|
||||
node = s.head
|
||||
}
|
||||
if node == nil {
|
||||
return lang.Nil[T](), exceptions.NewIndexOutOfBound("", nil)
|
||||
}
|
||||
|
||||
s.size.Add(-1)
|
||||
return node.value, nil
|
||||
}
|
||||
|
||||
func (s *ConcurrentLinkedStack[T]) CleanDeleted() {
|
||||
if s.deleted.Load() <= s.size.Load() {
|
||||
return
|
||||
}
|
||||
s.deleted.Store(0)
|
||||
node := &s.head
|
||||
for node != nil && *node != nil {
|
||||
if (*node).deleted {
|
||||
atomic.CompareAndSwapPointer(node, *node, (*node).next)
|
||||
} else {
|
||||
node = &(*node).next
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *ConcurrentLinkedStack[T]) Size() int {
|
||||
return int(s.size.Load())
|
||||
}
|
||||
|
||||
func (s *ConcurrentLinkedStack[T]) IsEmpty() bool {
|
||||
return s.head == nil
|
||||
}
|
||||
|
||||
func (s *ConcurrentLinkedStack[T]) Contains(element T) bool {
|
||||
return Contains[T](s, element)
|
||||
}
|
||||
|
||||
func (s *ConcurrentLinkedStack[T]) ContainsAll(c Collection[T]) bool {
|
||||
return ContainsAll[T](s, c)
|
||||
}
|
||||
|
||||
func (s *ConcurrentLinkedStack[T]) Add(element T) bool {
|
||||
exception := s.Push(element)
|
||||
exceptions.Print(exception)
|
||||
return exception == nil
|
||||
}
|
||||
|
||||
func (s *ConcurrentLinkedStack[T]) Remove(element T) exceptions.Exception {
|
||||
return Remove[T](s, element)
|
||||
}
|
||||
|
||||
func (s *ConcurrentLinkedStack[T]) AddAll(c Collection[T]) bool {
|
||||
return AddAll[T](s, c)
|
||||
}
|
||||
|
||||
func (s *ConcurrentLinkedStack[T]) RemoveAll(c Collection[T]) bool {
|
||||
return RemoveAll[T](s, c)
|
||||
}
|
||||
|
||||
func (s *ConcurrentLinkedStack[T]) RetainAll(c Collection[T]) bool {
|
||||
return RetainAll[T](s, c)
|
||||
}
|
||||
|
||||
func (s *ConcurrentLinkedStack[T]) Clear() {
|
||||
s.head = nil
|
||||
s.size.Store(0)
|
||||
}
|
||||
|
||||
func (s *ConcurrentLinkedStack[T]) MutableIterator() MutableIterator[T] {
|
||||
return &concurrentLinkedStackIterator[T]{s.head, nil}
|
||||
}
|
||||
|
||||
func (i *concurrentLinkedStackIterator[T]) HasNext() bool {
|
||||
return i.node.next != nil
|
||||
}
|
||||
|
||||
func (i *concurrentLinkedStackIterator[T]) Next() (T, exceptions.Exception) {
|
||||
if i.node == nil {
|
||||
return lang.Nil[T](), exceptions.NewIndexOutOfBound("", nil)
|
||||
}
|
||||
value := i.node.value
|
||||
i.node = i.node.next
|
||||
return value, nil
|
||||
}
|
||||
|
||||
func (i *concurrentLinkedStackIterator[T]) Remove() exceptions.Exception {
|
||||
if i.node == nil {
|
||||
return exceptions.NewIndexOutOfBound("", nil)
|
||||
}
|
||||
i.node.deleted = true
|
||||
i.node = i.node.next
|
||||
i.stack.size.Add(-1)
|
||||
i.stack.deleted.Add(1)
|
||||
i.stack.CleanDeleted()
|
||||
return nil
|
||||
}
|
@ -1,26 +1,58 @@
|
||||
package collections
|
||||
|
||||
import "github.com/tursom/GoCollections/exceptions"
|
||||
import "github.com/tursom/GoCollections/lang"
|
||||
import (
|
||||
"github.com/tursom/GoCollections/exceptions"
|
||||
"github.com/tursom/GoCollections/lang"
|
||||
)
|
||||
|
||||
type Iterator[T any] interface {
|
||||
type (
|
||||
// Iterator an iterator over a collection or another entity that can be represented as a sequence of elements.
|
||||
// Allows to sequentially access the elements
|
||||
Iterator[T any] interface {
|
||||
// HasNext return true if the iterator has more elements
|
||||
HasNext() bool
|
||||
// Next returns the next element in the iteration
|
||||
// return exceptions.IndexOutOfBound if there is no more element
|
||||
Next() (T, exceptions.Exception)
|
||||
}
|
||||
|
||||
type Iterable[T any] interface {
|
||||
Iterator() Iterator[T]
|
||||
}
|
||||
|
||||
type MutableIterator[T any] interface {
|
||||
// MutableIterator an iterator over a mutable collection.
|
||||
// Provides the ability to remove elements while iterating.
|
||||
MutableIterator[T any] interface {
|
||||
Iterator[T]
|
||||
// Remove removes from the underlying collection the last element returned by this iterator.
|
||||
Remove() exceptions.Exception
|
||||
}
|
||||
|
||||
type MutableIterable[T any] interface {
|
||||
// ListIterator an iterator over a collection that supports indexed access
|
||||
ListIterator[T any] interface {
|
||||
Iterator[T]
|
||||
HasPrevious() bool
|
||||
Previous() (T, exceptions.Exception)
|
||||
NextIndex() int
|
||||
PreviousIndex() int
|
||||
}
|
||||
|
||||
// MutableListIterator an iterator over a mutable collection that supports indexed access
|
||||
// Provides the ability to add, modify and remove elements while iterating.
|
||||
MutableListIterator[T any] interface {
|
||||
ListIterator[T]
|
||||
MutableIterator[T]
|
||||
Set(value T) exceptions.Exception
|
||||
Add(value T) exceptions.Exception
|
||||
}
|
||||
|
||||
// Iterable classes that inherit from this interface can be represented as a sequence of elements that can be iterated over.
|
||||
// param T
|
||||
Iterable[T any] interface {
|
||||
Iterator() Iterator[T]
|
||||
}
|
||||
|
||||
MutableIterable[T any] interface {
|
||||
Iterable[T]
|
||||
MutableIterator() MutableIterator[T]
|
||||
}
|
||||
)
|
||||
|
||||
func Loop[T any](iterable Iterable[T], f func(element T) exceptions.Exception) exceptions.Exception {
|
||||
if f == nil || iterable == nil {
|
||||
|
@ -1,97 +0,0 @@
|
||||
package collections
|
||||
|
||||
import (
|
||||
"github.com/tursom/GoCollections/exceptions"
|
||||
"github.com/tursom/GoCollections/lang"
|
||||
)
|
||||
|
||||
type MutableSubList[T lang.Object] struct {
|
||||
lang.BaseObject
|
||||
list MutableList[T]
|
||||
from, to int
|
||||
}
|
||||
|
||||
func NewMutableSubList[T lang.Object](list MutableList[T], from, to int) *MutableSubList[T] {
|
||||
return &MutableSubList[T]{lang.NewBaseObject(), list, from, to}
|
||||
}
|
||||
|
||||
func (s *MutableSubList[T]) Iterator() Iterator[T] {
|
||||
iterator := s.list.Iterator()
|
||||
for i := 0; i < s.from; i++ {
|
||||
_, err := iterator.Next()
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return iterator
|
||||
}
|
||||
|
||||
func (s *MutableSubList[T]) Size() int {
|
||||
return s.to - s.from
|
||||
}
|
||||
|
||||
func (s *MutableSubList[T]) IsEmpty() bool {
|
||||
return s.Size() == 0
|
||||
}
|
||||
|
||||
func (s *MutableSubList[T]) Contains(element T) bool {
|
||||
return Contains[T](s, element)
|
||||
}
|
||||
|
||||
func (s *MutableSubList[T]) ContainsAll(c Collection[T]) bool {
|
||||
return ContainsAll[T](s, c)
|
||||
}
|
||||
|
||||
func (s *MutableSubList[T]) Get(index int) (T, exceptions.Exception) {
|
||||
return s.list.Get(index + s.from)
|
||||
}
|
||||
|
||||
func (s *MutableSubList[T]) SubList(from, to int) List[T] {
|
||||
return NewSubList[T](s, from, to)
|
||||
}
|
||||
|
||||
func (s *MutableSubList[T]) MutableIterator() MutableIterator[T] {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *MutableSubList[T]) Add(_ T) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (s *MutableSubList[T]) Remove(element T) exceptions.Exception {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *MutableSubList[T]) AddAll(_ Collection[T]) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (s *MutableSubList[T]) RemoveAll(_ Collection[T]) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (s *MutableSubList[T]) RetainAll(_ Collection[T]) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (s *MutableSubList[T]) Clear() {
|
||||
}
|
||||
|
||||
func (s *MutableSubList[T]) Set(index int, element T) exceptions.Exception {
|
||||
if index >= s.to-s.from {
|
||||
return exceptions.NewIndexOutOfBound("", nil)
|
||||
}
|
||||
return s.list.Set(index+s.from, element)
|
||||
}
|
||||
|
||||
func (s *MutableSubList[T]) AddAtIndex(_ int, _ T) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (s *MutableSubList[T]) RemoveAt(index int) exceptions.Exception {
|
||||
return exceptions.NewOperationNotSupportedException("", nil)
|
||||
}
|
||||
|
||||
func (s *MutableSubList[T]) SubMutableList(from, to int) MutableList[T] {
|
||||
return NewMutableSubList[T](s.list, s.from+from, to)
|
||||
}
|
@ -5,9 +5,14 @@ import (
|
||||
"github.com/tursom/GoCollections/lang"
|
||||
)
|
||||
|
||||
type Queue[T lang.Object] interface {
|
||||
type (
|
||||
Queue[T lang.Object] interface {
|
||||
MutableIterable[T]
|
||||
|
||||
Offer(element T) exceptions.Exception
|
||||
OfferAndGetNode(element T) (QueueNode[T], exceptions.Exception)
|
||||
Poll() (T, exceptions.Exception)
|
||||
}
|
||||
|
||||
QueueNode[T lang.Object] = StackNode[T]
|
||||
)
|
||||
|
@ -1,10 +1,23 @@
|
||||
package collections
|
||||
|
||||
import "github.com/tursom/GoCollections/exceptions"
|
||||
import (
|
||||
"github.com/tursom/GoCollections/exceptions"
|
||||
"github.com/tursom/GoCollections/lang"
|
||||
)
|
||||
|
||||
type Stack[T any] interface {
|
||||
type (
|
||||
Stack[T any] interface {
|
||||
MutableIterable[T]
|
||||
|
||||
Push(element T) exceptions.Exception
|
||||
PushAndGetNode(element T) (StackNode[T], exceptions.Exception)
|
||||
Pop() (T, exceptions.Exception)
|
||||
}
|
||||
|
||||
StackNode[T lang.Object] interface {
|
||||
Set(value T) exceptions.Exception
|
||||
Get() (T, exceptions.Exception)
|
||||
Remove() exceptions.Exception
|
||||
RemoveAndGet() (T, exceptions.Exception)
|
||||
}
|
||||
)
|
||||
|
@ -1,51 +0,0 @@
|
||||
package collections
|
||||
|
||||
import (
|
||||
"github.com/tursom/GoCollections/exceptions"
|
||||
"github.com/tursom/GoCollections/lang"
|
||||
)
|
||||
|
||||
type SubList[T lang.Object] struct {
|
||||
lang.BaseObject
|
||||
list List[T]
|
||||
from, to int
|
||||
}
|
||||
|
||||
func NewSubList[T lang.Object](list List[T], from, to int) *SubList[T] {
|
||||
return &SubList[T]{lang.NewBaseObject(), list, from, to}
|
||||
}
|
||||
|
||||
func (s *SubList[T]) Iterator() Iterator[T] {
|
||||
iterator := s.list.Iterator()
|
||||
for i := 0; i < int(s.from); i++ {
|
||||
_, err := iterator.Next()
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return iterator
|
||||
}
|
||||
|
||||
func (s *SubList[T]) Size() int {
|
||||
return s.to - s.from
|
||||
}
|
||||
|
||||
func (s *SubList[T]) IsEmpty() bool {
|
||||
return s.Size() == 0
|
||||
}
|
||||
|
||||
func (s *SubList[T]) Contains(element T) bool {
|
||||
return Contains[T](s, element)
|
||||
}
|
||||
|
||||
func (s *SubList[T]) ContainsAll(c Collection[T]) bool {
|
||||
return ContainsAll[T](s, c)
|
||||
}
|
||||
|
||||
func (s *SubList[T]) Get(index int) (T, exceptions.Exception) {
|
||||
return s.list.Get(index + s.from)
|
||||
}
|
||||
|
||||
func (s *SubList[T]) SubList(from, to int) List[T] {
|
||||
return NewSubList[T](s, from, to)
|
||||
}
|
@ -1,36 +1,38 @@
|
||||
package collections
|
||||
package concurrent
|
||||
|
||||
import (
|
||||
"github.com/tursom/GoCollections/concurrent"
|
||||
"sync"
|
||||
|
||||
"github.com/tursom/GoCollections/collections"
|
||||
"github.com/tursom/GoCollections/exceptions"
|
||||
"github.com/tursom/GoCollections/lang"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type (
|
||||
// GoSyncMap an map use go sync.Map to store hash slot
|
||||
GoSyncMap[K lang.Object, V any] struct {
|
||||
NodeMap[K, V]
|
||||
collections.NodeMap[K, V]
|
||||
m sync.Map
|
||||
lock concurrent.RWLock
|
||||
lock RWLock
|
||||
}
|
||||
)
|
||||
|
||||
func NewGoSyncMap[K lang.Object, V any]() *GoSyncMap[K, V] {
|
||||
m := &GoSyncMap[K, V]{lock: &sync.RWMutex{}}
|
||||
m.MapNodeFinder = NewMapNodeFinderBySlot[K, V](m)
|
||||
m.MapNodeFinder = collections.NewMapNodeFinderBySlot[K, V](m)
|
||||
return m
|
||||
}
|
||||
|
||||
func (g *GoSyncMap[K, V]) ToString() lang.String {
|
||||
return MapToString[K, V](g)
|
||||
return collections.MapToString[K, V](g)
|
||||
}
|
||||
|
||||
func (g *GoSyncMap[K, V]) findSlot(k K) MapNode[K, V] {
|
||||
func (g *GoSyncMap[K, V]) findSlot(k K) collections.MapNode[K, V] {
|
||||
hashCode := lang.HashCode(k)
|
||||
p, _ := g.m.Load(hashCode)
|
||||
root := lang.Cast[*SimpleMapNode[K, V]](p)
|
||||
root := lang.Cast[*collections.SimpleMapNode[K, V]](p)
|
||||
if root == nil {
|
||||
root = &SimpleMapNode[K, V]{}
|
||||
root = &collections.SimpleMapNode[K, V]{}
|
||||
g.m.Store(hashCode, root)
|
||||
}
|
||||
return root
|
168
concurrent/LinkedQueue.go
Normal file
168
concurrent/LinkedQueue.go
Normal file
@ -0,0 +1,168 @@
|
||||
package concurrent
|
||||
|
||||
import (
|
||||
"github.com/tursom/GoCollections/collections"
|
||||
"github.com/tursom/GoCollections/exceptions"
|
||||
"github.com/tursom/GoCollections/lang"
|
||||
"github.com/tursom/GoCollections/lang/atomic"
|
||||
)
|
||||
|
||||
type (
|
||||
LinkedQueue[T lang.Object] struct {
|
||||
lang.BaseObject
|
||||
LinkedStack[T]
|
||||
end *linkedStackNode[T]
|
||||
}
|
||||
|
||||
linkedQueueIterator[T lang.Object] struct {
|
||||
node *linkedStackNode[T]
|
||||
queue *LinkedQueue[T]
|
||||
}
|
||||
)
|
||||
|
||||
func (q *LinkedQueue[T]) String() string {
|
||||
return collections.String[T](q)
|
||||
}
|
||||
|
||||
func NewLinkedQueue[T lang.Object]() *LinkedQueue[T] {
|
||||
return &LinkedQueue[T]{}
|
||||
}
|
||||
|
||||
func (q *LinkedQueue[T]) Iterator() collections.Iterator[T] {
|
||||
return q.MutableIterator()
|
||||
}
|
||||
|
||||
func (q *LinkedQueue[T]) Offer(element T) exceptions.Exception {
|
||||
_, err := q.offerAndGetNode(element)
|
||||
return err
|
||||
}
|
||||
|
||||
func (q *LinkedQueue[T]) OfferAndGetNode(element T) (collections.QueueNode[T], exceptions.Exception) {
|
||||
newNode, err := q.offerAndGetNode(element)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &linkedQueueIterator[T]{queue: q, node: newNode}, nil
|
||||
}
|
||||
|
||||
func (q *LinkedQueue[T]) offerAndGetNode(element T) (*linkedStackNode[T], exceptions.Exception) {
|
||||
newNode := &linkedStackNode[T]{value: element}
|
||||
q.size.Add(1)
|
||||
|
||||
var next **linkedStackNode[T]
|
||||
ref := q.end
|
||||
switch {
|
||||
case ref == nil:
|
||||
next = &q.head
|
||||
default:
|
||||
next = &ref.next
|
||||
}
|
||||
for !atomic.CompareAndSwapPointer(next, nil, newNode) {
|
||||
if ref == nil || ref.next == nil {
|
||||
next = &q.head
|
||||
ref = q.head
|
||||
} else {
|
||||
for ref.next != nil {
|
||||
ref = ref.next
|
||||
}
|
||||
next = &ref.next
|
||||
}
|
||||
}
|
||||
q.end = newNode
|
||||
return newNode, nil
|
||||
}
|
||||
|
||||
func (q *LinkedQueue[T]) Poll() (T, exceptions.Exception) {
|
||||
return q.Pop()
|
||||
}
|
||||
|
||||
func (q *LinkedQueue[T]) MutableIterator() collections.MutableIterator[T] {
|
||||
return &linkedQueueIterator[T]{queue: q, node: q.head}
|
||||
}
|
||||
|
||||
func (q *LinkedQueue[T]) Size() int {
|
||||
return int(q.size.Load())
|
||||
}
|
||||
|
||||
func (q *LinkedQueue[T]) IsEmpty() bool {
|
||||
return q.head == nil
|
||||
}
|
||||
|
||||
func (q *LinkedQueue[T]) Contains(element T) bool {
|
||||
return collections.Contains[T](q, element)
|
||||
}
|
||||
|
||||
func (q *LinkedQueue[T]) ContainsAll(collection collections.Collection[T]) bool {
|
||||
return collections.ContainsAll[T](q, collection)
|
||||
}
|
||||
|
||||
func (q *LinkedQueue[T]) Add(element T) bool {
|
||||
exception := q.Push(element)
|
||||
exceptions.Print(exception)
|
||||
return exception == nil
|
||||
}
|
||||
|
||||
func (q *LinkedQueue[T]) Remove(element T) exceptions.Exception {
|
||||
return collections.Remove[T](q, element)
|
||||
}
|
||||
|
||||
func (q *LinkedQueue[T]) AddAll(collection collections.Collection[T]) bool {
|
||||
return collections.AddAll[T](q, collection)
|
||||
}
|
||||
|
||||
func (q *LinkedQueue[T]) RemoveAll(collection collections.Collection[T]) bool {
|
||||
return collections.RemoveAll[T](q, collection)
|
||||
}
|
||||
|
||||
func (q *LinkedQueue[T]) RetainAll(collection collections.Collection[T]) bool {
|
||||
return collections.RetainAll[T](q, collection)
|
||||
}
|
||||
|
||||
func (q *LinkedQueue[T]) Clear() {
|
||||
q.head = nil
|
||||
q.end = nil
|
||||
q.size.Store(0)
|
||||
}
|
||||
|
||||
func (i *linkedQueueIterator[T]) HasNext() bool {
|
||||
for i.node != nil && i.node.deleted {
|
||||
i.node = i.node.next
|
||||
}
|
||||
return i.node != nil
|
||||
}
|
||||
|
||||
func (i *linkedQueueIterator[T]) Next() (T, exceptions.Exception) {
|
||||
value, err := i.Get()
|
||||
i.node = i.node.next
|
||||
for i.node != nil && i.node.deleted {
|
||||
i.node = i.node.next
|
||||
}
|
||||
return value, err
|
||||
}
|
||||
|
||||
func (i *linkedQueueIterator[T]) Get() (T, exceptions.Exception) {
|
||||
return i.node.value, nil
|
||||
}
|
||||
|
||||
func (i *linkedQueueIterator[T]) Set(value T) exceptions.Exception {
|
||||
i.node.value = value
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *linkedQueueIterator[T]) Remove() exceptions.Exception {
|
||||
_, err := i.RemoveAndGet()
|
||||
return err
|
||||
}
|
||||
|
||||
func (i *linkedQueueIterator[T]) RemoveAndGet() (T, exceptions.Exception) {
|
||||
if i.node == nil {
|
||||
return lang.Nil[T](), nil
|
||||
}
|
||||
load := i.node
|
||||
load.deleted = true
|
||||
i.queue.size.Add(-1)
|
||||
i.queue.deleted.Add(1)
|
||||
i.queue.CleanDeleted()
|
||||
i.node = load.next
|
||||
return load.value, nil
|
||||
}
|
@ -1,13 +1,14 @@
|
||||
package collections
|
||||
package concurrent
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/tursom/GoCollections/exceptions"
|
||||
"github.com/tursom/GoCollections/lang"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/tursom/GoCollections/exceptions"
|
||||
"github.com/tursom/GoCollections/lang"
|
||||
)
|
||||
|
||||
type data struct {
|
||||
@ -21,12 +22,12 @@ func (d *data) String() string {
|
||||
}
|
||||
|
||||
func TestConcurrentLinkedQueue_NodeSize(t *testing.T) {
|
||||
fmt.Println(unsafe.Alignof(concurrentLinkedStackNode[*data]{}))
|
||||
fmt.Println(unsafe.Sizeof(concurrentLinkedStackNode[*data]{}))
|
||||
fmt.Println(unsafe.Alignof(linkedStackNode[*data]{}))
|
||||
fmt.Println(unsafe.Sizeof(linkedStackNode[*data]{}))
|
||||
}
|
||||
|
||||
func TestConcurrentLinkedQueue_Push(t *testing.T) {
|
||||
queue := NewConcurrentLinkedQueue[*data]()
|
||||
queue := NewLinkedQueue[*data]()
|
||||
cond := sync.WaitGroup{}
|
||||
cond.Add(1)
|
||||
for i := 0; i < 10; i++ {
|
||||
@ -46,11 +47,11 @@ func TestConcurrentLinkedQueue_Push(t *testing.T) {
|
||||
|
||||
func TestConcurrentLinkedQueue_ThreadSafe(t *testing.T) {
|
||||
times := 400000
|
||||
queue := NewConcurrentLinkedQueue[*data]()
|
||||
queue := NewLinkedQueue[*data]()
|
||||
for i := 0; i < 100; i++ {
|
||||
id := i
|
||||
go func() {
|
||||
//nodes := make([]ConcurrentLinkedQueueNode[*data], 0)
|
||||
//nodes := make([]QueueNode[*data], 0)
|
||||
for j := 0; j < times; j++ {
|
||||
_ = queue.Offer(&data{id: id, index: j})
|
||||
//node, _ := queue.OfferAndGetNode(&data{id: id, index: j})
|
||||
@ -81,8 +82,8 @@ func TestConcurrentLinkedQueue_ThreadSafe(t *testing.T) {
|
||||
}
|
||||
|
||||
func Test_concurrentLinkedQueueIterator_Remove(t *testing.T) {
|
||||
queue := NewConcurrentLinkedQueue[lang.Int]()
|
||||
nodes := make([]ConcurrentLinkedQueueNode[lang.Int], 0)
|
||||
queue := NewLinkedQueue[lang.Int]()
|
||||
nodes := make([]QueueNode[lang.Int], 0)
|
||||
for i := 0; i < 1000; i++ {
|
||||
node, _ := queue.OfferAndGetNode(lang.Int(i))
|
||||
nodes = append(nodes, node)
|
175
concurrent/LinkedStack.go
Normal file
175
concurrent/LinkedStack.go
Normal file
@ -0,0 +1,175 @@
|
||||
package concurrent
|
||||
|
||||
import (
|
||||
"github.com/tursom/GoCollections/collections"
|
||||
"github.com/tursom/GoCollections/exceptions"
|
||||
"github.com/tursom/GoCollections/lang"
|
||||
"github.com/tursom/GoCollections/lang/atomic"
|
||||
)
|
||||
|
||||
type (
|
||||
LinkedStack[T lang.Object] struct {
|
||||
lang.BaseObject
|
||||
size atomic.Int32
|
||||
deleted atomic.Int32
|
||||
head *linkedStackNode[T]
|
||||
}
|
||||
|
||||
linkedStackNode[T any] struct {
|
||||
deleted bool
|
||||
next *linkedStackNode[T]
|
||||
value T
|
||||
}
|
||||
|
||||
linkedStackIterator[T lang.Object] struct {
|
||||
node *linkedStackNode[T]
|
||||
stack *LinkedStack[T]
|
||||
}
|
||||
)
|
||||
|
||||
func (s *LinkedStack[T]) String() string {
|
||||
return collections.String[T](s)
|
||||
}
|
||||
|
||||
func NewLinkedStack[T lang.Object]() *LinkedStack[T] {
|
||||
return &LinkedStack[T]{}
|
||||
}
|
||||
|
||||
func (s *LinkedStack[T]) Iterator() collections.Iterator[T] {
|
||||
return s.MutableIterator()
|
||||
}
|
||||
|
||||
func (s *LinkedStack[T]) Push(element T) exceptions.Exception {
|
||||
s.push(element)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *LinkedStack[T]) PushAndGetNode(element T) collections.StackNode[T] {
|
||||
return &linkedStackIterator[T]{
|
||||
node: s.push(element),
|
||||
stack: s,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *LinkedStack[T]) push(element T) *linkedStackNode[T] {
|
||||
newNode := &linkedStackNode[T]{value: element, next: s.head}
|
||||
for !atomic.CompareAndSwapPointer(&s.head, newNode.next, newNode) {
|
||||
newNode.next = s.head
|
||||
}
|
||||
s.size.Add(1)
|
||||
return newNode
|
||||
}
|
||||
|
||||
func (s *LinkedStack[T]) Pop() (T, exceptions.Exception) {
|
||||
node := s.head
|
||||
for node != nil && (!atomic.CompareAndSwapPointer(&s.head, node, node.next) || node.deleted) {
|
||||
node = s.head
|
||||
}
|
||||
if node == nil {
|
||||
return lang.Nil[T](), exceptions.NewIndexOutOfBound("", nil)
|
||||
}
|
||||
|
||||
s.size.Add(-1)
|
||||
return node.value, nil
|
||||
}
|
||||
|
||||
func (s *LinkedStack[T]) CleanDeleted() {
|
||||
if s.deleted.Load() <= s.size.Load() {
|
||||
return
|
||||
}
|
||||
s.deleted.Store(0)
|
||||
node := &s.head
|
||||
for node != nil && *node != nil {
|
||||
if (*node).deleted {
|
||||
atomic.CompareAndSwapPointer(node, *node, (*node).next)
|
||||
} else {
|
||||
node = &(*node).next
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *LinkedStack[T]) Size() int {
|
||||
return int(s.size.Load())
|
||||
}
|
||||
|
||||
func (s *LinkedStack[T]) IsEmpty() bool {
|
||||
return s.head == nil
|
||||
}
|
||||
|
||||
func (s *LinkedStack[T]) Contains(element T) bool {
|
||||
return collections.Contains[T](s, element)
|
||||
}
|
||||
|
||||
func (s *LinkedStack[T]) ContainsAll(c collections.Collection[T]) bool {
|
||||
return collections.ContainsAll[T](s, c)
|
||||
}
|
||||
|
||||
func (s *LinkedStack[T]) Add(element T) bool {
|
||||
exception := s.Push(element)
|
||||
exceptions.Print(exception)
|
||||
return exception == nil
|
||||
}
|
||||
|
||||
func (s *LinkedStack[T]) Remove(element T) exceptions.Exception {
|
||||
return collections.Remove[T](s, element)
|
||||
}
|
||||
|
||||
func (s *LinkedStack[T]) AddAll(c collections.Collection[T]) bool {
|
||||
return collections.AddAll[T](s, c)
|
||||
}
|
||||
|
||||
func (s *LinkedStack[T]) RemoveAll(c collections.Collection[T]) bool {
|
||||
return collections.RemoveAll[T](s, c)
|
||||
}
|
||||
|
||||
func (s *LinkedStack[T]) RetainAll(c collections.Collection[T]) bool {
|
||||
return collections.RetainAll[T](s, c)
|
||||
}
|
||||
|
||||
func (s *LinkedStack[T]) Clear() {
|
||||
s.head = nil
|
||||
s.size.Store(0)
|
||||
}
|
||||
|
||||
func (s *LinkedStack[T]) MutableIterator() collections.MutableIterator[T] {
|
||||
return &linkedStackIterator[T]{s.head, nil}
|
||||
}
|
||||
|
||||
func (i *linkedStackIterator[T]) HasNext() bool {
|
||||
return i.node.next != nil
|
||||
}
|
||||
|
||||
func (i *linkedStackIterator[T]) Next() (T, exceptions.Exception) {
|
||||
if i.node == nil {
|
||||
return lang.Nil[T](), exceptions.NewIndexOutOfBound("", nil)
|
||||
}
|
||||
value := i.node.value
|
||||
i.node = i.node.next
|
||||
return value, nil
|
||||
}
|
||||
|
||||
func (i *linkedStackIterator[T]) Remove() exceptions.Exception {
|
||||
if i.node == nil {
|
||||
return exceptions.NewIndexOutOfBound("", nil)
|
||||
}
|
||||
i.node.deleted = true
|
||||
i.node = i.node.next
|
||||
i.stack.size.Add(-1)
|
||||
i.stack.deleted.Add(1)
|
||||
i.stack.CleanDeleted()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *linkedStackIterator[T]) Get() (T, exceptions.Exception) {
|
||||
return i.node.value, nil
|
||||
}
|
||||
|
||||
func (i *linkedStackIterator[T]) Set(value T) exceptions.Exception {
|
||||
i.node.value = value
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *linkedStackIterator[T]) RemoveAndGet() (T, exceptions.Exception) {
|
||||
i.node.deleted = true
|
||||
return i.node.value, nil
|
||||
}
|
@ -1,24 +1,25 @@
|
||||
package collections
|
||||
package concurrent
|
||||
|
||||
import (
|
||||
"github.com/tursom/GoCollections/concurrent"
|
||||
"sync"
|
||||
|
||||
"github.com/tursom/GoCollections/collections"
|
||||
"github.com/tursom/GoCollections/exceptions"
|
||||
"github.com/tursom/GoCollections/lang"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type (
|
||||
LockedMutableList[T lang.Object] struct {
|
||||
list MutableList[T]
|
||||
lock concurrent.RWLock
|
||||
list collections.MutableList[T]
|
||||
lock RWLock
|
||||
}
|
||||
lockedMutableListIterator[T lang.Object] struct {
|
||||
iterator MutableIterator[T]
|
||||
lock concurrent.RWLock
|
||||
iterator collections.MutableIterator[T]
|
||||
lock RWLock
|
||||
}
|
||||
)
|
||||
|
||||
func MutableListWithLock[T lang.Object](list MutableList[T]) MutableList[T] {
|
||||
func MutableListWithLock[T lang.Object](list collections.MutableList[T]) collections.MutableList[T] {
|
||||
return &LockedMutableList[T]{
|
||||
list: list,
|
||||
lock: &sync.RWMutex{},
|
||||
@ -26,10 +27,10 @@ func MutableListWithLock[T lang.Object](list MutableList[T]) MutableList[T] {
|
||||
}
|
||||
|
||||
func (l *LockedMutableList[T]) String() string {
|
||||
return String[T](l)
|
||||
return collections.String[T](l)
|
||||
}
|
||||
|
||||
func (l *LockedMutableList[T]) Iterator() Iterator[T] {
|
||||
func (l *LockedMutableList[T]) Iterator() collections.Iterator[T] {
|
||||
return l.MutableIterator()
|
||||
}
|
||||
|
||||
@ -51,14 +52,14 @@ func (l *LockedMutableList[T]) Contains(element T) bool {
|
||||
return l.list.Contains(element)
|
||||
}
|
||||
|
||||
func (l *LockedMutableList[T]) ContainsAll(c Collection[T]) bool {
|
||||
func (l *LockedMutableList[T]) ContainsAll(c collections.Collection[T]) bool {
|
||||
l.lock.RLock()
|
||||
defer l.lock.RUnlock()
|
||||
|
||||
return l.list.ContainsAll(c)
|
||||
}
|
||||
|
||||
func (l *LockedMutableList[T]) MutableIterator() MutableIterator[T] {
|
||||
func (l *LockedMutableList[T]) MutableIterator() collections.MutableIterator[T] {
|
||||
return &lockedMutableListIterator[T]{l.list.MutableIterator(), l.lock}
|
||||
}
|
||||
|
||||
@ -76,21 +77,21 @@ func (l *LockedMutableList[T]) Remove(element T) exceptions.Exception {
|
||||
return l.list.Remove(element)
|
||||
}
|
||||
|
||||
func (l *LockedMutableList[T]) AddAll(c Collection[T]) bool {
|
||||
func (l *LockedMutableList[T]) AddAll(c collections.Collection[T]) bool {
|
||||
l.lock.Lock()
|
||||
defer l.lock.Unlock()
|
||||
|
||||
return l.list.AddAll(c)
|
||||
}
|
||||
|
||||
func (l *LockedMutableList[T]) RemoveAll(c Collection[T]) bool {
|
||||
func (l *LockedMutableList[T]) RemoveAll(c collections.Collection[T]) bool {
|
||||
l.lock.Lock()
|
||||
defer l.lock.Unlock()
|
||||
|
||||
return l.list.RemoveAll(c)
|
||||
}
|
||||
|
||||
func (l *LockedMutableList[T]) RetainAll(c Collection[T]) bool {
|
||||
func (l *LockedMutableList[T]) RetainAll(c collections.Collection[T]) bool {
|
||||
l.lock.Lock()
|
||||
defer l.lock.Unlock()
|
||||
|
||||
@ -111,7 +112,7 @@ func (l *LockedMutableList[T]) Get(index int) (T, exceptions.Exception) {
|
||||
return l.list.Get(index)
|
||||
}
|
||||
|
||||
func (l *LockedMutableList[T]) SubList(from, to int) List[T] {
|
||||
func (l *LockedMutableList[T]) SubList(from, to int) collections.List[T] {
|
||||
return l.SubMutableList(from, to)
|
||||
}
|
||||
|
||||
@ -136,7 +137,7 @@ func (l *LockedMutableList[T]) RemoveAt(index int) exceptions.Exception {
|
||||
return l.list.RemoveAt(index)
|
||||
}
|
||||
|
||||
func (l *LockedMutableList[T]) SubMutableList(from, to int) MutableList[T] {
|
||||
func (l *LockedMutableList[T]) SubMutableList(from, to int) collections.MutableList[T] {
|
||||
return &LockedMutableList[T]{l.list.SubMutableList(from, to), l.lock}
|
||||
}
|
||||
|
@ -116,8 +116,8 @@ func PackagePanic(panic any, exceptionMessage string) Exception {
|
||||
}
|
||||
switch panic.(type) {
|
||||
case error:
|
||||
return NewRuntimeException("", DefaultExceptionConfig().SetCause(panic))
|
||||
return NewRuntimeException(exceptionMessage, DefaultExceptionConfig().SetCause(panic))
|
||||
default:
|
||||
return NewRuntimeException("", DefaultExceptionConfig())
|
||||
return NewPackageException(panic, nil)
|
||||
}
|
||||
}
|
||||
|
@ -33,12 +33,14 @@ func (p *PackageException) Err() any {
|
||||
|
||||
func UnpackException(err any) any {
|
||||
for err != nil {
|
||||
switch err.(type) {
|
||||
switch e := err.(type) {
|
||||
case *PackageException:
|
||||
err = err.(*PackageException).Err()
|
||||
return err
|
||||
return e.Err()
|
||||
case Exception:
|
||||
err = err.(Exception).Cause()
|
||||
err = e.Cause()
|
||||
if err == nil {
|
||||
return e
|
||||
}
|
||||
default:
|
||||
return err
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user