add go generic support

This commit is contained in:
tursom 2022-03-21 11:02:41 +08:00
parent 1257f74ca3
commit 67220737dc
30 changed files with 613 additions and 378 deletions

BIN
GoCollections Normal file → Executable file

Binary file not shown.

View File

@ -1,54 +1,57 @@
package collections
import "github.com/tursom/GoCollections/exceptions"
import (
"github.com/tursom/GoCollections/exceptions"
"github.com/tursom/GoCollections/lang"
)
type ArrayList struct {
array []interface{}
used uint32
type ArrayList[T lang.Object] struct {
array []T
used int
}
func NewArrayList() *ArrayList {
return &ArrayList{
make([]interface{}, 16),
func NewArrayList[T lang.Object]() *ArrayList[T] {
return &ArrayList[T]{
make([]T, 16),
0,
}
}
func NewArrayListByCapacity(cap uint32) *ArrayList {
return &ArrayList{
make([]interface{}, cap),
func NewArrayListByCapacity[T lang.Object](cap int) *ArrayList[T] {
return &ArrayList[T]{
make([]T, cap),
0,
}
}
func (a ArrayList) String() string {
return String(a)
func (a ArrayList[T]) String() string {
return String[T](a)
}
func (a ArrayList) Iterator() Iterator {
func (a ArrayList[T]) Iterator() Iterator[T] {
return a.MutableIterator()
}
func (a ArrayList) Size() uint32 {
func (a ArrayList[T]) Size() int {
return a.used
}
func (a ArrayList) IsEmpty() bool {
func (a ArrayList[T]) IsEmpty() bool {
return a.Size() == 0
}
func (a ArrayList) Contains(element interface{}) bool {
return Contains(a, element)
func (a ArrayList[T]) Contains(element T) bool {
return Contains[T](a, element)
}
func (a ArrayList) ContainsAll(c Collection) bool {
return ContainsAll(a, c)
func (a ArrayList[T]) ContainsAll(c Collection[T]) bool {
return ContainsAll[T](a, c)
}
func (a *ArrayList) Add(element interface{}) bool {
if a.used >= uint32(len(a.array)) {
func (a *ArrayList[T]) Add(element T) bool {
if a.used >= len(a.array) {
oldArray := a.array
a.array = make([]interface{}, a.used*2)
a.array = make([]T, a.used*2)
copy(a.array, oldArray)
}
a.array[a.used] = element
@ -56,62 +59,61 @@ func (a *ArrayList) Add(element interface{}) bool {
return true
}
func (a ArrayList) IndexOf(element interface{}) int {
var i uint32 = 0
for ; i < a.used; i++ {
if a.array[i] == element {
func (a ArrayList[T]) IndexOf(element T) int {
for i := 0; i < a.used; i++ {
if lang.Equals(element, a.array[i]) {
return int(i)
}
}
return -1
}
func (a *ArrayList) Remove(element interface{}) exceptions.Exception {
func (a *ArrayList[T]) Remove(element T) exceptions.Exception {
index := a.IndexOf(element)
if index < 0 {
return exceptions.NewElementNotFoundException("", true)
return exceptions.NewElementNotFoundException("", nil)
} else {
return a.RemoveAt(uint32(index))
return a.RemoveAt(int(index))
}
}
func (a *ArrayList) AddAll(c Collection) bool {
return AddAll(a, c)
func (a *ArrayList[T]) AddAll(c Collection[T]) bool {
return AddAll[T](a, c)
}
func (a *ArrayList) RemoveAll(c Collection) bool {
return RemoveAll(a, c)
func (a *ArrayList[T]) RemoveAll(c Collection[T]) bool {
return RemoveAll[T](a, c)
}
func (a *ArrayList) RetainAll(c Collection) bool {
return RetainAll(a, c)
func (a *ArrayList[T]) RetainAll(c Collection[T]) bool {
return RetainAll[T](a, c)
}
func (a *ArrayList) Clear() {
func (a *ArrayList[T]) Clear() {
a.used = 0
}
func (a ArrayList) Get(index uint32) (interface{}, exceptions.Exception) {
func (a ArrayList[T]) Get(index int) (T, exceptions.Exception) {
if index >= a.used {
return nil, exceptions.NewIndexOutOfBound("", true)
return lang.Nil[T](), exceptions.NewIndexOutOfBound("", nil)
} else {
return a.array[index], nil
}
}
func (a ArrayList) SubList(from, to uint32) List {
return NewSubList(a, from, to)
func (a ArrayList[T]) SubList(from, to int) List[T] {
return NewSubList[T](a, from, to)
}
func (a *ArrayList) Set(index uint32, element interface{}) exceptions.Exception {
func (a *ArrayList[T]) Set(index int, element T) exceptions.Exception {
if index >= a.used {
return exceptions.NewIndexOutOfBound("", true)
return exceptions.NewIndexOutOfBound("", nil)
}
a.array[index] = element
return nil
}
func (a *ArrayList) AddAtIndex(index uint32, element interface{}) bool {
func (a *ArrayList[T]) AddAtIndex(index int, element T) bool {
if !a.Add(element) {
return false
}
@ -125,9 +127,9 @@ func (a *ArrayList) AddAtIndex(index uint32, element interface{}) bool {
return true
}
func (a *ArrayList) RemoveAt(index uint32) exceptions.Exception {
func (a *ArrayList[T]) RemoveAt(index int) exceptions.Exception {
if index >= a.used {
return exceptions.NewIndexOutOfBound("", true)
return exceptions.NewIndexOutOfBound("", nil)
}
array := a.array
@ -138,33 +140,33 @@ func (a *ArrayList) RemoveAt(index uint32) exceptions.Exception {
return nil
}
func (a *ArrayList) SubMutableList(from, to uint32) MutableList {
func (a *ArrayList[T]) SubMutableList(from, to int) MutableList[T] {
panic("implement me")
}
func (a *ArrayList) MutableIterator() MutableIterator {
return &arrayListIterator{a, 0}
func (a *ArrayList[T]) MutableIterator() MutableIterator[T] {
return &arrayListIterator[T]{a, 0}
}
type arrayListIterator struct {
arrayList *ArrayList
index uint32
type arrayListIterator[T lang.Object] struct {
arrayList *ArrayList[T]
index int
}
func (a *arrayListIterator) HasNext() bool {
func (a *arrayListIterator[T]) HasNext() bool {
return a.index < a.arrayList.used
}
func (a *arrayListIterator) Next() (interface{}, exceptions.Exception) {
func (a *arrayListIterator[T]) Next() (T, exceptions.Exception) {
value, err := a.arrayList.Get(a.index)
if err != nil {
return nil, err
return lang.Nil[T](), err
}
a.index++
return value, nil
}
func (a *arrayListIterator) Remove() exceptions.Exception {
func (a *arrayListIterator[T]) Remove() exceptions.Exception {
err := a.arrayList.RemoveAt(a.index - 1)
if err != nil {
return err

View File

@ -3,72 +3,73 @@ package collections
import (
"fmt"
"github.com/tursom/GoCollections/exceptions"
"github.com/tursom/GoCollections/lang"
"strings"
)
type (
Collection interface {
Iterator() Iterator
Size() uint32
Collection[T any] interface {
Iterator() Iterator[T]
Size() int
IsEmpty() bool
Contains(element interface{}) bool
ContainsAll(c Collection) bool
Contains(element T) bool
ContainsAll(c Collection[T]) bool
}
MutableCollection interface {
Iterator() Iterator
Size() uint32
MutableCollection[T any] interface {
Iterator() Iterator[T]
Size() int
IsEmpty() bool
Contains(element interface{}) bool
ContainsAll(c Collection) bool
Contains(element T) bool
ContainsAll(c Collection[T]) bool
MutableIterator() MutableIterator
Add(element interface{}) bool
Remove(element interface{}) exceptions.Exception
AddAll(c Collection) bool
RemoveAll(c Collection) bool
RetainAll(c Collection) bool
MutableIterator() MutableIterator[T]
Add(element T) bool
Remove(element T) exceptions.Exception
AddAll(c Collection[T]) bool
RemoveAll(c Collection[T]) bool
RetainAll(c Collection[T]) bool
Clear()
}
List interface {
Iterator() Iterator
Size() uint32
List[T any] interface {
Iterator() Iterator[T]
Size() int
IsEmpty() bool
Contains(element interface{}) bool
ContainsAll(c Collection) bool
Contains(element T) bool
ContainsAll(c Collection[T]) bool
Get(index uint32) (interface{}, exceptions.Exception)
SubList(from, to uint32) List
Get(index int) (T, exceptions.Exception)
SubList(from, to int) List[T]
}
MutableList interface {
Iterator() Iterator
Size() uint32
MutableList[T any] interface {
Iterator() Iterator[T]
Size() int
IsEmpty() bool
Contains(element interface{}) bool
ContainsAll(c Collection) bool
Contains(element T) bool
ContainsAll(c Collection[T]) bool
MutableIterator() MutableIterator
Add(element interface{}) bool
Remove(element interface{}) exceptions.Exception
AddAll(c Collection) bool
RemoveAll(c Collection) bool
RetainAll(c Collection) bool
MutableIterator() MutableIterator[T]
Add(element T) bool
Remove(element T) exceptions.Exception
AddAll(c Collection[T]) bool
RemoveAll(c Collection[T]) bool
RetainAll(c Collection[T]) bool
Clear()
Get(index uint32) (interface{}, exceptions.Exception)
SubList(from, to uint32) List
Get(index int) (T, exceptions.Exception)
SubList(from, to int) List[T]
Set(index uint32, element interface{}) exceptions.Exception
AddAtIndex(index uint32, element interface{}) bool
RemoveAt(index uint32) exceptions.Exception
SubMutableList(from, to uint32) MutableList
Set(index int, element T) exceptions.Exception
AddAtIndex(index int, element T) bool
RemoveAt(index int) exceptions.Exception
SubMutableList(from, to int) MutableList[T]
}
)
func ContainsAll(l Collection, collection Collection) bool {
return Loop(collection, func(e interface{}) exceptions.Exception {
func ContainsAll[T lang.Object](l Collection[T], collection Collection[T]) bool {
return Loop[T](collection, func(e T) exceptions.Exception {
if l.Contains(e) {
return nil
} else {
@ -77,8 +78,8 @@ func ContainsAll(l Collection, collection Collection) bool {
}) == nil
}
func AddAll(l MutableCollection, collection Collection) bool {
return Loop(collection, func(e interface{}) exceptions.Exception {
func AddAll[T any](l MutableCollection[T], collection Collection[T]) bool {
return Loop[T](collection, func(e T) exceptions.Exception {
if !l.Add(e) {
return exceptions.CollectionLoopFinished
}
@ -86,7 +87,7 @@ func AddAll(l MutableCollection, collection Collection) bool {
}) == nil
}
func String(l Iterable) string {
func String[T any](l Iterable[T]) string {
iterator := l.Iterator()
if !iterator.HasNext() {
return "[]"

View File

@ -2,58 +2,59 @@ package collections
import (
"github.com/tursom/GoCollections/exceptions"
"github.com/tursom/GoCollections/lang"
"sync/atomic"
"unsafe"
)
type ConcurrentLinkedQueue struct {
head *concurrentLinkedQueueNode
type ConcurrentLinkedQueue[T lang.Object] struct {
head *concurrentLinkedQueueNode[T]
}
func (c ConcurrentLinkedQueue) String() string {
return String(c)
func (c ConcurrentLinkedQueue[T]) String() string {
return String[T](c)
}
type concurrentLinkedQueueNode struct {
value interface{}
prev *concurrentLinkedQueueNode
next *concurrentLinkedQueueNode
type concurrentLinkedQueueNode[T any] struct {
value T
prev *concurrentLinkedQueueNode[T]
next *concurrentLinkedQueueNode[T]
}
type concurrentLinkedQueueIterator struct {
head *concurrentLinkedQueueNode
node *concurrentLinkedQueueNode
type concurrentLinkedQueueIterator[T any] struct {
head *concurrentLinkedQueueNode[T]
node *concurrentLinkedQueueNode[T]
}
func NewConcurrentLinkedQueue() *ConcurrentLinkedQueue {
head := &concurrentLinkedQueueNode{}
func NewConcurrentLinkedQueue[T lang.Object]() *ConcurrentLinkedQueue[T] {
head := &concurrentLinkedQueueNode[T]{}
head.prev = head
head.next = head
return &ConcurrentLinkedQueue{head}
return &ConcurrentLinkedQueue[T]{head}
}
func (c ConcurrentLinkedQueue) Iterator() Iterator {
func (c ConcurrentLinkedQueue[T]) Iterator() Iterator[T] {
return c.MutableIterator()
}
func (c *ConcurrentLinkedQueue) Push(element interface{}) exceptions.Exception {
newNode := &concurrentLinkedQueueNode{element, c.head.prev, c.head}
func (c *ConcurrentLinkedQueue[T]) Push(element T) exceptions.Exception {
newNode := &concurrentLinkedQueueNode[T]{element, c.head.prev, c.head}
p := (*unsafe.Pointer)(unsafe.Pointer(&c.head.prev))
for !atomic.CompareAndSwapPointer(p, unsafe.Pointer(newNode.prev), unsafe.Pointer(newNode)) {
for !atomic.CompareAndSwapPointer(p, unsafe.Pointer(&*newNode.prev), unsafe.Pointer(newNode)) {
newNode.prev = c.head.prev
}
atomic.CompareAndSwapPointer(
(*unsafe.Pointer)(unsafe.Pointer(&newNode.prev.next)),
unsafe.Pointer(c.head),
unsafe.Pointer(&*c.head),
unsafe.Pointer(newNode),
)
return nil
}
func (c *ConcurrentLinkedQueue) Offer() (interface{}, exceptions.Exception) {
func (c *ConcurrentLinkedQueue[T]) Offer() (T, exceptions.Exception) {
next := c.head.next
if next == c.head {
return nil, exceptions.NewIndexOutOfBound("", true)
return lang.Nil[T](), exceptions.NewIndexOutOfBound("", nil)
}
p := (*unsafe.Pointer)(unsafe.Pointer(&next.next.prev))
@ -62,95 +63,95 @@ func (c *ConcurrentLinkedQueue) Offer() (interface{}, exceptions.Exception) {
next = c.head.next
p = (*unsafe.Pointer)(unsafe.Pointer(&next.prev))
if next == nil {
return nil, exceptions.NewIndexOutOfBound("", true)
return lang.Nil[T](), exceptions.NewIndexOutOfBound("", nil)
}
}
return next.value, nil
}
func (node *concurrentLinkedQueueNode) removeNode(p *unsafe.Pointer) bool {
func (node *concurrentLinkedQueueNode[T]) removeNode(p *unsafe.Pointer) bool {
if p == nil {
p = (*unsafe.Pointer)(unsafe.Pointer(&node.next.prev))
}
if !atomic.CompareAndSwapPointer(p, unsafe.Pointer(node), unsafe.Pointer(node.prev)) {
if !atomic.CompareAndSwapPointer(p, unsafe.Pointer(node), unsafe.Pointer(&*node.prev)) {
return false
}
atomic.CompareAndSwapPointer(
(*unsafe.Pointer)(unsafe.Pointer(&node.prev.next)),
unsafe.Pointer(node),
unsafe.Pointer(node.next),
unsafe.Pointer(&*node.next),
)
return true
}
func (c *ConcurrentLinkedQueue) MutableIterator() MutableIterator {
return &concurrentLinkedQueueIterator{c.head, c.head}
func (c *ConcurrentLinkedQueue[T]) MutableIterator() MutableIterator[T] {
return &concurrentLinkedQueueIterator[T]{c.head, c.head}
}
func (c *concurrentLinkedQueueIterator) HasNext() bool {
func (c *concurrentLinkedQueueIterator[T]) HasNext() bool {
return c.node.next != c.head
}
func (c *concurrentLinkedQueueIterator) Next() (interface{}, exceptions.Exception) {
func (c *concurrentLinkedQueueIterator[T]) Next() (T, exceptions.Exception) {
c.node = c.node.next
if c.node == c.head {
return nil, exceptions.NewIndexOutOfBound("", true)
return lang.Nil[T](), exceptions.NewIndexOutOfBound("", nil)
}
return c.node.value, nil
}
func (c *concurrentLinkedQueueIterator) Remove() exceptions.Exception {
func (c *concurrentLinkedQueueIterator[T]) Remove() exceptions.Exception {
if c.node == c.head {
return exceptions.NewIndexOutOfBound("", true)
return exceptions.NewIndexOutOfBound("", nil)
}
c.node.removeNode(nil)
c.node = c.node.prev
return nil
}
func (c *ConcurrentLinkedQueue) Size() uint32 {
size, err := Size(c)
func (c *ConcurrentLinkedQueue[T]) Size() int {
size, err := Size[T](c)
exceptions.Print(err)
return size
}
func (c *ConcurrentLinkedQueue) IsEmpty() bool {
func (c *ConcurrentLinkedQueue[T]) IsEmpty() bool {
return c.head.next == c.head
}
func (c *ConcurrentLinkedQueue) Contains(element interface{}) bool {
return Contains(c, element)
func (c *ConcurrentLinkedQueue[T]) Contains(element T) bool {
return Contains[T](c, element)
}
func (c *ConcurrentLinkedQueue) ContainsAll(collection Collection) bool {
return ContainsAll(c, collection)
func (c *ConcurrentLinkedQueue[T]) ContainsAll(collection Collection[T]) bool {
return ContainsAll[T](c, collection)
}
func (c *ConcurrentLinkedQueue) Add(element interface{}) bool {
func (c *ConcurrentLinkedQueue[T]) Add(element T) bool {
exception := c.Push(element)
exceptions.Print(exception)
return exception == nil
}
func (c *ConcurrentLinkedQueue) Remove(element interface{}) exceptions.Exception {
return Remove(c, element)
func (c *ConcurrentLinkedQueue[T]) Remove(element T) exceptions.Exception {
return Remove[T](c, element)
}
func (c *ConcurrentLinkedQueue) AddAll(collection Collection) bool {
return AddAll(c, collection)
func (c *ConcurrentLinkedQueue[T]) AddAll(collection Collection[T]) bool {
return AddAll[T](c, collection)
}
func (c *ConcurrentLinkedQueue) RemoveAll(collection Collection) bool {
return RemoveAll(c, collection)
func (c *ConcurrentLinkedQueue[T]) RemoveAll(collection Collection[T]) bool {
return RemoveAll[T](c, collection)
}
func (c *ConcurrentLinkedQueue) RetainAll(collection Collection) bool {
return RetainAll(c, collection)
func (c *ConcurrentLinkedQueue[T]) RetainAll(collection Collection[T]) bool {
return RetainAll[T](c, collection)
}
func (c *ConcurrentLinkedQueue) Clear() {
head := &concurrentLinkedQueueNode{}
func (c *ConcurrentLinkedQueue[T]) Clear() {
head := &concurrentLinkedQueueNode[T]{}
head.prev = head
head.next = head
c.head = head

View File

@ -2,88 +2,89 @@ package collections
import (
"github.com/tursom/GoCollections/exceptions"
"github.com/tursom/GoCollections/lang"
"sync/atomic"
"unsafe"
)
type ConcurrentLinkedStack struct {
head *concurrentLinkedStackNode
type ConcurrentLinkedStack[T any] struct {
head *concurrentLinkedStackNode[T]
p *unsafe.Pointer
}
func (c ConcurrentLinkedStack) String() string {
return String(c)
func (c ConcurrentLinkedStack[T]) String() string {
return String[T](c)
}
type concurrentLinkedStackNode struct {
value interface{}
next *concurrentLinkedStackNode
type concurrentLinkedStackNode[T any] struct {
value T
next *concurrentLinkedStackNode[T]
}
type concurrentLinkedStackIterator struct {
node *concurrentLinkedStackNode
prev *concurrentLinkedStackNode
type concurrentLinkedStackIterator[T any] struct {
node *concurrentLinkedStackNode[T]
prev *concurrentLinkedStackNode[T]
}
func NewConcurrentLinkedStack() *ConcurrentLinkedStack {
head := &concurrentLinkedStackNode{}
return &ConcurrentLinkedStack{head, (*unsafe.Pointer)(unsafe.Pointer(&head.next))}
func NewConcurrentLinkedStack[T any]() *ConcurrentLinkedStack[T] {
head := &concurrentLinkedStackNode[T]{}
return &ConcurrentLinkedStack[T]{head, (*unsafe.Pointer)(unsafe.Pointer(&head.next))}
}
func (c ConcurrentLinkedStack) Iterator() Iterator {
func (c ConcurrentLinkedStack[T]) Iterator() Iterator[T] {
return c.MutableIterator()
}
func (c *ConcurrentLinkedStack) Push(element interface{}) exceptions.Exception {
newNode := &concurrentLinkedStackNode{element, c.head.next}
func (c *ConcurrentLinkedStack[T]) Push(element T) exceptions.Exception {
newNode := &concurrentLinkedStackNode[T]{element, c.head.next}
np := unsafe.Pointer(newNode)
for !atomic.CompareAndSwapPointer(c.p, unsafe.Pointer(newNode.next), np) {
for !atomic.CompareAndSwapPointer(c.p, unsafe.Pointer(&*newNode.next), np) {
}
return nil
}
func (c *ConcurrentLinkedStack) Pop() (interface{}, exceptions.Exception) {
func (c *ConcurrentLinkedStack[T]) Pop() (T, exceptions.Exception) {
next := c.head.next
if next == nil {
return nil, exceptions.NewIndexOutOfBound("", true)
return lang.Nil[T](), exceptions.NewIndexOutOfBound("", nil)
}
p := (*unsafe.Pointer)(unsafe.Pointer(&c.head.next))
if !atomic.CompareAndSwapPointer(p, unsafe.Pointer(next), unsafe.Pointer(next.next)) {
if !atomic.CompareAndSwapPointer(p, unsafe.Pointer(&*next), unsafe.Pointer(&*next.next)) {
next = c.head.next
if next == nil {
return nil, exceptions.NewIndexOutOfBound("", true)
return lang.Nil[T](), exceptions.NewIndexOutOfBound("", nil)
}
}
return next.value, nil
}
func (c *ConcurrentLinkedStack) MutableIterator() MutableIterator {
return &concurrentLinkedStackIterator{c.head, nil}
func (c *ConcurrentLinkedStack[T]) MutableIterator() MutableIterator[T] {
return &concurrentLinkedStackIterator[T]{c.head, nil}
}
func (c *concurrentLinkedStackIterator) HasNext() bool {
func (c *concurrentLinkedStackIterator[T]) HasNext() bool {
return c.node.next != nil
}
func (c *concurrentLinkedStackIterator) Next() (interface{}, exceptions.Exception) {
func (c *concurrentLinkedStackIterator[T]) Next() (T, exceptions.Exception) {
c.prev = c.node
c.node = c.node.next
if c.node == nil {
return nil, exceptions.NewIndexOutOfBound("", true)
return lang.Nil[T](), exceptions.NewIndexOutOfBound("", nil)
}
return c.node.value, nil
}
func (c *concurrentLinkedStackIterator) Remove() exceptions.Exception {
func (c *concurrentLinkedStackIterator[T]) Remove() exceptions.Exception {
if c.node == nil {
return exceptions.NewIndexOutOfBound("", true)
return exceptions.NewIndexOutOfBound("", nil)
}
next := c.node.next
p := (*unsafe.Pointer)(unsafe.Pointer(&c.prev.next))
atomic.CompareAndSwapPointer(p, unsafe.Pointer(c.node), unsafe.Pointer(next))
atomic.CompareAndSwapPointer(p, unsafe.Pointer(&*c.node), unsafe.Pointer(&*next))
return nil
}

View File

@ -1,47 +1,48 @@
package collections
import "github.com/tursom/GoCollections/exceptions"
import "github.com/tursom/GoCollections/lang"
type Iterator interface {
type Iterator[T any] interface {
HasNext() bool
Next() (interface{}, exceptions.Exception)
Next() (T, exceptions.Exception)
}
type Iterable interface {
Iterator() Iterator
type Iterable[T any] interface {
Iterator() Iterator[T]
}
type MutableIterator interface {
type MutableIterator[T any] interface {
HasNext() bool
Next() (interface{}, exceptions.Exception)
Next() (T, exceptions.Exception)
Remove() exceptions.Exception
}
type MutableIterable interface {
Iterator() Iterator
MutableIterator() MutableIterator
type MutableIterable[T any] interface {
Iterator() Iterator[T]
MutableIterator() MutableIterator[T]
}
func Loop(iterable Iterable, f func(element interface{}) exceptions.Exception) exceptions.Exception {
func Loop[T any](iterable Iterable[T], f func(element T) exceptions.Exception) exceptions.Exception {
if f == nil || iterable == nil {
return exceptions.NewNPE("", true)
return exceptions.NewNPE("", nil)
}
return LoopIterator(iterable.Iterator(), f)
}
func LoopMutable(
iterable MutableIterable,
f func(element interface{}, iterator MutableIterator) (err exceptions.Exception),
func LoopMutable[T any](
iterable MutableIterable[T],
f func(element T, iterator MutableIterator[T]) (err exceptions.Exception),
) exceptions.Exception {
if f == nil || iterable == nil {
return exceptions.NewNPE("", true)
return exceptions.NewNPE("", nil)
}
return LoopMutableIterator(iterable.MutableIterator(), f)
}
func LoopIterator(iterator Iterator, f func(element interface{}) exceptions.Exception) exceptions.Exception {
func LoopIterator[T any](iterator Iterator[T], f func(element T) exceptions.Exception) exceptions.Exception {
if f == nil || iterator == nil {
return exceptions.NewNPE("", true)
return exceptions.NewNPE("", nil)
}
for iterator.HasNext() {
next, err := iterator.Next()
@ -56,12 +57,12 @@ func LoopIterator(iterator Iterator, f func(element interface{}) exceptions.Exce
return nil
}
func LoopMutableIterator(
iterator MutableIterator,
f func(element interface{}, iterator MutableIterator) (err exceptions.Exception),
func LoopMutableIterator[T any](
iterator MutableIterator[T],
f func(element T, iterator MutableIterator[T]) (err exceptions.Exception),
) exceptions.Exception {
if f == nil || iterator == nil {
return exceptions.NewNPE("", true)
return exceptions.NewNPE("", nil)
}
for iterator.HasNext() {
next, err := iterator.Next()
@ -76,7 +77,7 @@ func LoopMutableIterator(
return nil
}
func Size(iterable Iterable) (size uint32, err exceptions.Exception) {
func Size[T any](iterable Iterable[T]) (size int, err exceptions.Exception) {
iterator := iterable.Iterator()
for iterator.HasNext() {
_, err = iterator.Next()
@ -88,26 +89,26 @@ func Size(iterable Iterable) (size uint32, err exceptions.Exception) {
return
}
func Contains(l Iterable, element interface{}) bool {
return Loop(l, func(e interface{}) exceptions.Exception {
if e == element {
func Contains[T lang.Object](l Iterable[T], element T) bool {
return Loop(l, func(e T) exceptions.Exception {
if lang.Equals(element, e) {
return exceptions.ElementFound
}
return nil
}) != nil
}
func Remove(l MutableIterable, element interface{}) exceptions.Exception {
return LoopMutable(l, func(e interface{}, iterator MutableIterator) (err exceptions.Exception) {
if element == e {
func Remove[T lang.Object](l MutableIterable[T], element T) exceptions.Exception {
return LoopMutable(l, func(e T, iterator MutableIterator[T]) (err exceptions.Exception) {
if lang.Equals(element, e) {
return iterator.Remove()
}
return nil
})
}
func RemoveAll(l MutableIterable, collection Collection) bool {
return LoopMutable(l, func(element interface{}, iterator MutableIterator) (err exceptions.Exception) {
func RemoveAll[T any](l MutableIterable[T], collection Collection[T]) bool {
return LoopMutable(l, func(element T, iterator MutableIterator[T]) (err exceptions.Exception) {
if collection.Contains(element) {
return iterator.Remove()
}
@ -115,8 +116,8 @@ func RemoveAll(l MutableIterable, collection Collection) bool {
}) == nil
}
func RetainAll(l MutableIterable, collection Collection) bool {
return LoopMutable(l, func(element interface{}, iterator MutableIterator) exceptions.Exception {
func RetainAll[T any](l MutableIterable[T], collection Collection[T]) bool {
return LoopMutable(l, func(element T, iterator MutableIterator[T]) exceptions.Exception {
if !collection.Contains(element) {
return iterator.Remove()
}
@ -124,8 +125,8 @@ func RetainAll(l MutableIterable, collection Collection) bool {
}) == nil
}
func Clear(l MutableIterable) exceptions.Exception {
return LoopMutable(l, func(element interface{}, iterator MutableIterator) (err exceptions.Exception) {
func Clear[T any](l MutableIterable[T]) exceptions.Exception {
return LoopMutable(l, func(element T, iterator MutableIterator[T]) (err exceptions.Exception) {
return iterator.Remove()
})
}

View File

@ -2,57 +2,58 @@ package collections
import (
"github.com/tursom/GoCollections/exceptions"
"github.com/tursom/GoCollections/lang"
)
type (
LinkedList struct {
head *linkedListNode
size uint32
LinkedList[T lang.Object] struct {
head *linkedListNode[T]
size int
}
linkedListNode struct {
prev, next *linkedListNode
value interface{}
linkedListNode[T lang.Object] struct {
prev, next *linkedListNode[T]
value T
}
)
func (l LinkedList) String() string {
return String(l)
func (l LinkedList[T]) String() string {
return String[T](l)
}
func NewLinkedList() *LinkedList {
tail := &linkedListNode{}
func NewLinkedList[T lang.Object]() *LinkedList[T] {
tail := &linkedListNode[T]{}
tail.prev = tail
tail.next = tail
return &LinkedList{tail, 0}
return &LinkedList[T]{tail, 0}
}
func (l LinkedList) Size() uint32 {
func (l LinkedList[T]) Size() int {
return l.size
}
func (l LinkedList) IsEmpty() bool {
func (l LinkedList[T]) IsEmpty() bool {
return l.size == 0
}
func (l LinkedList) Contains(element interface{}) bool {
return Contains(&l, element)
func (l LinkedList[T]) Contains(element T) bool {
return Contains[T](&l, element)
}
func (l LinkedList) ContainsAll(c Collection) bool {
return ContainsAll(&l, c)
func (l LinkedList[T]) ContainsAll(c Collection[T]) bool {
return ContainsAll[T](&l, c)
}
func (l *LinkedList) Add(element interface{}) bool {
func (l *LinkedList[T]) Add(element T) bool {
l.size++
node := &linkedListNode{l.head.prev, l.head, element}
node := &linkedListNode[T]{l.head.prev, l.head, element}
node.next.prev = node
node.prev.next = node
return true
}
func (l *LinkedList) Remove(element interface{}) exceptions.Exception {
err := LoopMutable(l, func(e interface{}, iterator MutableIterator) exceptions.Exception {
if element == e {
func (l *LinkedList[T]) Remove(element T) exceptions.Exception {
err := LoopMutable[T](l, func(e T, iterator MutableIterator[T]) exceptions.Exception {
if lang.Equals(element, e) {
iterator.Remove()
return exceptions.CollectionLoopFinished
}
@ -61,32 +62,32 @@ func (l *LinkedList) Remove(element interface{}) exceptions.Exception {
if err != nil {
return nil
} else {
return exceptions.NewElementNotFoundException("", true)
return exceptions.NewElementNotFoundException("", nil)
}
}
func (l *LinkedList) AddAll(c Collection) bool {
return AddAll(l, c)
func (l *LinkedList[T]) AddAll(c Collection[T]) bool {
return AddAll[T](l, c)
}
func (l *LinkedList) RemoveAll(c Collection) bool {
return RemoveAll(l, c)
func (l *LinkedList[T]) RemoveAll(c Collection[T]) bool {
return RemoveAll[T](l, c)
}
func (l *LinkedList) RetainAll(c Collection) bool {
return RetainAll(l, c)
func (l *LinkedList[T]) RetainAll(c Collection[T]) bool {
return RetainAll[T](l, c)
}
func (l *LinkedList) Clear() {
func (l *LinkedList[T]) Clear() {
l.head.next = l.head
l.size = 0
}
func (l LinkedList) SubList(from, to uint32) List {
return NewSubList(l, from, to)
func (l LinkedList[T]) SubList(from, to int) List[T] {
return NewSubList[T](l, from, to)
}
func (l *LinkedList) Set(index uint32, element interface{}) exceptions.Exception {
func (l *LinkedList[T]) Set(index int, element T) exceptions.Exception {
node := l.head
for node != l.head {
if index == 0 {
@ -95,15 +96,15 @@ func (l *LinkedList) Set(index uint32, element interface{}) exceptions.Exception
}
index--
}
return exceptions.NewIndexOutOfBound("", true)
return exceptions.NewIndexOutOfBound("", nil)
}
func (l *LinkedList) AddAtIndex(index uint32, element interface{}) bool {
func (l *LinkedList[T]) AddAtIndex(index int, element T) bool {
node := l.head
for node != l.head {
if index == 0 {
l.size++
node.next = &linkedListNode{node, node.next, element}
node.next = &linkedListNode[T]{node, node.next, element}
node.next.next.prev = node.next
return true
}
@ -112,7 +113,7 @@ func (l *LinkedList) AddAtIndex(index uint32, element interface{}) bool {
return false
}
func (l *LinkedList) RemoveAt(index uint32) exceptions.Exception {
func (l *LinkedList[T]) RemoveAt(index int) exceptions.Exception {
node := l.head
for node != l.head {
if index == 0 {
@ -122,14 +123,14 @@ func (l *LinkedList) RemoveAt(index uint32) exceptions.Exception {
}
index--
}
return exceptions.NewIndexOutOfBound("", true)
return exceptions.NewIndexOutOfBound("", nil)
}
func (l *LinkedList) SubMutableList(from, to uint32) MutableList {
return NewMutableSubList(l, from, to)
func (l *LinkedList[T]) SubMutableList(from, to int) MutableList[T] {
return NewMutableSubList[T](l, from, to)
}
func (l LinkedList) Get(index uint32) (interface{}, exceptions.Exception) {
func (l LinkedList[T]) Get(index int) (T, exceptions.Exception) {
node := l.head
for node != l.head {
if index == 0 {
@ -138,44 +139,44 @@ func (l LinkedList) Get(index uint32) (interface{}, exceptions.Exception) {
index--
}
return nil, exceptions.NewIndexOutOfBound("", true)
return lang.Nil[T](), exceptions.NewIndexOutOfBound("", nil)
}
func (l LinkedList) Iterator() Iterator {
func (l LinkedList[T]) Iterator() Iterator[T] {
return l.MutableIterator()
}
func (l *LinkedList) MutableIterator() MutableIterator {
return &linkedListIterator{l, l.head.next, l.head}
func (l *LinkedList[T]) MutableIterator() MutableIterator[T] {
return &linkedListIterator[T]{l, l.head.next, l.head}
}
type linkedListIterator struct {
list *LinkedList
node, head *linkedListNode
type linkedListIterator[T lang.Object] struct {
list *LinkedList[T]
node, head *linkedListNode[T]
}
func (l *linkedListIterator) HasNext() bool {
func (l *linkedListIterator[T]) HasNext() bool {
return l.node != l.head
}
func (l *linkedListIterator) Next() (interface{}, exceptions.Exception) {
func (l *linkedListIterator[T]) Next() (T, exceptions.Exception) {
if l.node == l.head {
return nil, exceptions.NewIndexOutOfBound("", true)
return lang.Nil[T](), exceptions.NewIndexOutOfBound("", nil)
}
l.node = l.node.next
return l.node.prev.value, nil
}
func (l *linkedListIterator) Remove() exceptions.Exception {
func (l *linkedListIterator[T]) Remove() exceptions.Exception {
if l.node.prev == l.head {
return exceptions.NewIndexOutOfBound("", true)
return exceptions.NewIndexOutOfBound("", nil)
}
l.node.prev.remove()
l.list.size--
return nil
}
func (l *linkedListNode) remove() {
func (l *linkedListNode[T]) remove() {
l.next.prev = l.prev
l.prev.next = l.next
}

View File

@ -1,19 +1,22 @@
package collections
import "github.com/tursom/GoCollections/exceptions"
import (
"github.com/tursom/GoCollections/exceptions"
"github.com/tursom/GoCollections/lang"
)
type MutableSubList struct {
list MutableList
from, to uint32
type MutableSubList[T lang.Object] struct {
list MutableList[T]
from, to int
}
func NewMutableSubList(list MutableList, from, to uint32) *MutableSubList {
return &MutableSubList{list, from, to}
func NewMutableSubList[T lang.Object](list MutableList[T], from, to int) MutableList[T] {
return &MutableSubList[T]{list, from, to}
}
func (s *MutableSubList) Iterator() Iterator {
func (s *MutableSubList[T]) Iterator() Iterator[T] {
iterator := s.list.Iterator()
for i := 0; i < int(s.from); i++ {
for i := 0; i < s.from; i++ {
_, err := iterator.Next()
if err != nil {
return nil
@ -22,72 +25,72 @@ func (s *MutableSubList) Iterator() Iterator {
return iterator
}
func (s *MutableSubList) Size() uint32 {
func (s *MutableSubList[T]) Size() int {
return s.to - s.from
}
func (s *MutableSubList) IsEmpty() bool {
func (s *MutableSubList[T]) IsEmpty() bool {
return s.Size() == 0
}
func (s *MutableSubList) Contains(element interface{}) bool {
return Contains(s, element)
func (s *MutableSubList[T]) Contains(element T) bool {
return Contains[T](s, element)
}
func (s *MutableSubList) ContainsAll(c Collection) bool {
return ContainsAll(s, c)
func (s *MutableSubList[T]) ContainsAll(c Collection[T]) bool {
return ContainsAll[T](s, c)
}
func (s *MutableSubList) Get(index uint32) (interface{}, exceptions.Exception) {
func (s *MutableSubList[T]) Get(index int) (T, exceptions.Exception) {
return s.list.Get(index + s.from)
}
func (s *MutableSubList) SubList(from, to uint32) List {
return NewSubList(s, from, to)
func (s *MutableSubList[T]) SubList(from, to int) List[T] {
return NewSubList[T](s, from, to)
}
func (s *MutableSubList) MutableIterator() MutableIterator {
func (s *MutableSubList[T]) MutableIterator() MutableIterator[T] {
return nil
}
func (s *MutableSubList) Add(_ interface{}) bool {
func (s *MutableSubList[T]) Add(_ T) bool {
return false
}
func (s *MutableSubList) Remove(element interface{}) exceptions.Exception {
func (s *MutableSubList[T]) Remove(element T) exceptions.Exception {
return nil
}
func (s *MutableSubList) AddAll(_ Collection) bool {
func (s *MutableSubList[T]) AddAll(_ Collection[T]) bool {
return false
}
func (s *MutableSubList) RemoveAll(_ Collection) bool {
func (s *MutableSubList[T]) RemoveAll(_ Collection[T]) bool {
return false
}
func (s *MutableSubList) RetainAll(_ Collection) bool {
func (s *MutableSubList[T]) RetainAll(_ Collection[T]) bool {
return false
}
func (s *MutableSubList) Clear() {
func (s *MutableSubList[T]) Clear() {
}
func (s *MutableSubList) Set(index uint32, element interface{}) exceptions.Exception {
func (s *MutableSubList[T]) Set(index int, element T) exceptions.Exception {
if index >= s.to-s.from {
return exceptions.NewIndexOutOfBound("", true)
return exceptions.NewIndexOutOfBound("", nil)
}
return s.list.Set(index+s.from, element)
}
func (s *MutableSubList) AddAtIndex(_ uint32, _ interface{}) bool {
func (s *MutableSubList[T]) AddAtIndex(_ int, _ T) bool {
return false
}
func (s *MutableSubList) RemoveAt(index uint32) exceptions.Exception {
return exceptions.NewOperationNotSupportedException("", true)
func (s *MutableSubList[T]) RemoveAt(index int) exceptions.Exception {
return exceptions.NewOperationNotSupportedException("", nil)
}
func (s *MutableSubList) SubMutableList(from, to uint32) MutableList {
return NewMutableSubList(s.list, s.from+from, to)
func (s *MutableSubList[T]) SubMutableList(from, to int) MutableList[T] {
return NewMutableSubList[T](s.list, s.from+from, to)
}

View File

@ -1,13 +1,16 @@
package collections
import "github.com/tursom/GoCollections/exceptions"
import (
"github.com/tursom/GoCollections/exceptions"
"github.com/tursom/GoCollections/lang"
)
type Queue interface {
type Queue[T lang.Object] interface {
// Iterator MutableIterable
Iterator() Iterator
Iterator() Iterator[T]
// MutableIterator MutableIterable
MutableIterator() *linkedListIterator
MutableIterator() *linkedListIterator[T]
Push(element interface{}) exceptions.Exception
Offer() (interface{}, exceptions.Exception)
Push(element T) exceptions.Exception
Offer() (T, exceptions.Exception)
}

View File

@ -2,12 +2,12 @@ package collections
import "github.com/tursom/GoCollections/exceptions"
type Stack interface {
type Stack[T any] interface {
// Iterator MutableIterable
Iterator() Iterator
Iterator() Iterator[T]
// MutableIterator MutableIterable
MutableIterator() MutableIterator
MutableIterator() MutableIterator[T]
Push(element interface{}) exceptions.Exception
Pop() (interface{}, exceptions.Exception)
Push(element T) exceptions.Exception
Pop() (T, exceptions.Exception)
}

View File

@ -1,17 +1,20 @@
package collections
import "github.com/tursom/GoCollections/exceptions"
import (
"github.com/tursom/GoCollections/exceptions"
"github.com/tursom/GoCollections/lang"
)
type SubList struct {
list List
from, to uint32
type SubList[T lang.Object] struct {
list List[T]
from, to int
}
func NewSubList(list List, from, to uint32) *SubList {
return &SubList{list, from, to}
func NewSubList[T lang.Object](list List[T], from, to int) List[T] {
return &SubList[T]{list, from, to}
}
func (s *SubList) Iterator() Iterator {
func (s *SubList[T]) Iterator() Iterator[T] {
iterator := s.list.Iterator()
for i := 0; i < int(s.from); i++ {
_, err := iterator.Next()
@ -22,26 +25,26 @@ func (s *SubList) Iterator() Iterator {
return iterator
}
func (s *SubList) Size() uint32 {
func (s *SubList[T]) Size() int {
return s.to - s.from
}
func (s *SubList) IsEmpty() bool {
func (s *SubList[T]) IsEmpty() bool {
return s.Size() == 0
}
func (s *SubList) Contains(element interface{}) bool {
return Contains(s, element)
func (s *SubList[T]) Contains(element T) bool {
return Contains[T](s, element)
}
func (s *SubList) ContainsAll(c Collection) bool {
return ContainsAll(s, c)
func (s *SubList[T]) ContainsAll(c Collection[T]) bool {
return ContainsAll[T](s, c)
}
func (s *SubList) Get(index uint32) (interface{}, exceptions.Exception) {
func (s *SubList[T]) Get(index int) (T, exceptions.Exception) {
return s.list.Get(index + s.from)
}
func (s *SubList) SubList(from, to uint32) List {
return NewSubList(s, from, to)
func (s *SubList[T]) SubList(from, to int) List[T] {
return NewSubList[T](s, from, to)
}

View File

@ -1,5 +1,5 @@
package exceptions
var ElementFound = NewRuntimeException("", "element found", false, nil)
var ElementNotFound = NewRuntimeException("", "element not found", false, nil)
var CollectionLoopFinished = NewRuntimeException("", "collection loop finished", false, nil)
var ElementFound = NewRuntimeException("", "element found", DefaultExceptionConfig().SetGetStackTrace(false))
var ElementNotFound = NewRuntimeException("", "element not found", DefaultExceptionConfig().SetGetStackTrace(false))
var CollectionLoopFinished = NewRuntimeException("", "collection loop finished", DefaultExceptionConfig().SetGetStackTrace(false))

View File

@ -4,13 +4,13 @@ type ElementNotFoundException struct {
RuntimeException
}
func NewElementNotFoundException(message interface{}, getStackTrace bool) ElementNotFoundException {
return ElementNotFoundException{
func NewElementNotFoundException(message interface{}, config *ExceptionConfig) *ElementNotFoundException {
config.AddSkipStack(1)
return &ElementNotFoundException{
NewRuntimeException(
message,
"exception caused ElementNotFoundException:",
getStackTrace,
nil,
config,
),
}
}

View File

@ -92,7 +92,7 @@ func Package(err error) Exception {
case Exception:
return err.(Exception)
}
return NewRuntimeException(err, "", true, err)
return NewRuntimeException(err, "", DefaultExceptionConfig().SetCause(err))
}
func PackageAny(err interface{}) Exception {
@ -103,7 +103,7 @@ func PackageAny(err interface{}) Exception {
case error:
return Package(err.(error))
default:
return NewRuntimeException(err, "", true, nil)
return NewRuntimeException(err, "", DefaultExceptionConfig())
}
}
@ -116,13 +116,13 @@ func PackagePanic(panic interface{}, exceptionMessage string) Exception {
return NewRuntimeException(
panic,
exceptionMessage,
true, panic,
DefaultExceptionConfig().SetCause(panic),
)
default:
return NewRuntimeException(
panic,
exceptionMessage,
true, nil,
DefaultExceptionConfig(),
)
}
}

View File

@ -0,0 +1,47 @@
package exceptions
type ExceptionConfig struct {
SkipStack int
GetStackTrace bool
Cause interface{}
}
func DefaultExceptionConfig() *ExceptionConfig {
return &ExceptionConfig{
SkipStack: 0,
GetStackTrace: true,
Cause: nil,
}
}
func (c *ExceptionConfig) SetSkipStack(skipStack int) *ExceptionConfig {
if c == nil {
return DefaultExceptionConfig().SetSkipStack(skipStack)
}
c.SkipStack = skipStack
return c
}
func (c *ExceptionConfig) SetGetStackTrace(getStackTrace bool) *ExceptionConfig {
if c == nil {
return DefaultExceptionConfig().SetGetStackTrace(getStackTrace)
}
c.GetStackTrace = getStackTrace
return c
}
func (c *ExceptionConfig) SetCause(cause interface{}) *ExceptionConfig {
if c == nil {
return DefaultExceptionConfig().SetCause(cause)
}
c.Cause = cause
return c
}
func (c *ExceptionConfig) AddSkipStack(skipStack int) *ExceptionConfig {
if c == nil {
return DefaultExceptionConfig().AddSkipStack(skipStack)
}
c.SkipStack += skipStack
return c
}

View File

@ -4,13 +4,24 @@ type IndexOutOfBound struct {
RuntimeException
}
func NewIndexOutOfBound(message interface{}, getStackTrace bool) IndexOutOfBound {
return IndexOutOfBound{
func NewIndexOutOfBound(message interface{}, config *ExceptionConfig) *IndexOutOfBound {
config.AddSkipStack(1)
return &IndexOutOfBound{
NewRuntimeException(
message,
"exception caused IndexOutOfBound:",
getStackTrace,
nil,
config,
),
}
}
func CatchIndexOutOfBound[T any](f func() T, config *ExceptionConfig) (r T, err Exception) {
defer func() {
r := recover()
if r != nil {
err = NewIndexOutOfBound(r, config.AddSkipStack(3))
}
}()
r = f()
return
}

View File

@ -4,13 +4,13 @@ type NPE struct {
RuntimeException
}
func NewNPE(message interface{}, getStackTrace bool) NPE {
return NPE{
func NewNPE(message interface{}, config *ExceptionConfig) *NPE {
config.AddSkipStack(1)
return &NPE{
NewRuntimeException(
message,
"exception caused NullPointerException:",
getStackTrace,
nil,
config,
),
}
}

View File

@ -4,13 +4,13 @@ type OperationNotSupportedException struct {
RuntimeException
}
func NewOperationNotSupportedException(message interface{}, getStackTrace bool) OperationNotSupportedException {
return OperationNotSupportedException{
func NewOperationNotSupportedException(message interface{}, config *ExceptionConfig) *OperationNotSupportedException {
config.AddSkipStack(1)
return &OperationNotSupportedException{
NewRuntimeException(
message,
"exception caused OperationNotSupportedException:",
getStackTrace,
nil,
config,
),
}
}

View File

@ -5,9 +5,10 @@ type PackageException struct {
err interface{}
}
func NewPackageException(err interface{}, exceptionMessage string, getStackTrace bool) *PackageException {
func NewPackageException(err interface{}, exceptionMessage string, config *ExceptionConfig) *PackageException {
config.AddSkipStack(1)
return &PackageException{
RuntimeException: NewRuntimeException(err, exceptionMessage, getStackTrace, nil),
RuntimeException: NewRuntimeException(err, exceptionMessage, config),
err: err,
}
}

View File

@ -14,10 +14,14 @@ type RuntimeException struct {
cause Exception
}
func NewRuntimeException(message interface{}, exceptionMessage string, getStackTrace bool, cause interface{}) RuntimeException {
func NewRuntimeException(message interface{}, exceptionMessage string, config *ExceptionConfig) RuntimeException {
if config == nil {
config = DefaultExceptionConfig()
}
var stackTrace []StackTrace = nil
if getStackTrace {
stackTrace = GetStackTrace()
if config.GetStackTrace {
stackTrace = GetStackTraceSkipDeep(config.SkipStack + 1)
}
if len(exceptionMessage) == 0 {
@ -25,12 +29,13 @@ func NewRuntimeException(message interface{}, exceptionMessage string, getStackT
}
var causeException Exception = nil
if cause != nil {
switch cause.(type) {
if config.Cause != nil {
switch config.Cause.(type) {
case Exception:
causeException = cause.(Exception)
causeException = config.Cause.(Exception)
default:
causeException = NewPackageException(cause, "exception caused:", false)
causeException = NewPackageException(config.Cause, "exception caused:", DefaultExceptionConfig().
SetGetStackTrace(false))
}
}

View File

@ -44,22 +44,17 @@ func (s StackTrace) WriteTo(builder *strings.Builder) {
}
func GetStackTrace() []StackTrace {
stackTraceMax := 16
stackTraceUsed := 0
stackTrace := make([]StackTrace, stackTraceMax)
for i := 1; ; i++ {
return GetStackTraceSkipDeep(0)
}
func GetStackTraceSkipDeep(deep int) []StackTrace {
stackTrace := make([]StackTrace, 0, 16)
for i := deep + 1; ; i++ {
pc, file, line, ok := runtime.Caller(i)
if !ok {
break
}
if stackTraceUsed == stackTraceMax {
stackTraceMax *= 2
stackTraceOld := stackTrace
stackTrace = make([]StackTrace, stackTraceMax)
copy(stackTrace, stackTraceOld)
}
stackTrace[stackTraceUsed] = StackTrace{pc, file, line}
stackTraceUsed++
stackTrace = append(stackTrace, StackTrace{pc, file, line})
}
return stackTrace[0:stackTraceUsed]
return stackTrace
}

2
go.mod
View File

@ -1,3 +1,3 @@
module github.com/tursom/GoCollections
go 1.17
go 1.18

29
lang/Comparable.go Normal file
View File

@ -0,0 +1,29 @@
package lang
type Comparable[T any] interface {
Compare(t T) int
}
func Compare[T any, E Comparable[T]](e E, t T) int {
//if e == nil {
// panic(exceptions.NewNPE("LessThan compare from an null object", true))
//}
return e.Compare(t)
}
func LessThan[T any, E Comparable[T]](e E, t T) bool {
return e.Compare(t) < 0
}
func MoreThan[T any, E Comparable[T]](e E, t T) bool {
return e.Compare(t) > 0
}
func LessThanEqual[T any, E Comparable[T]](e E, t T) bool {
return e.Compare(t) <= 0
}
func MoreThanEqual[T any, E Comparable[T]](e E, t T) bool {
return e.Compare(t) >= 0
}

15
lang/Int.go Normal file
View File

@ -0,0 +1,15 @@
package lang
type Int int
func (i Int) Equals(e Object) bool {
i2, ok := e.(Int)
if !ok {
return false
}
return i == i2
}
func (i Int) Compare(t Int) int {
return int(t - i)
}

6
lang/Lang.go Normal file
View File

@ -0,0 +1,6 @@
package lang
func Nil[T any]() T {
var n T
return n
}

12
lang/Object.go Normal file
View File

@ -0,0 +1,12 @@
package lang
type Object interface {
Equals(e Object) bool
}
func Equals(e Object, t Object) bool {
if e == nil {
return t == nil
}
return e.Equals(t)
}

15
main.go
View File

@ -4,6 +4,7 @@ import (
"fmt"
"github.com/tursom/GoCollections/collections"
"github.com/tursom/GoCollections/exceptions"
"github.com/tursom/GoCollections/lang"
"time"
)
@ -16,24 +17,24 @@ func main() {
})
exceptions.Print(err)
list := collections.NewConcurrentLinkedQueue()
target := collections.NewArrayListByCapacity(10000)
list := collections.NewConcurrentLinkedQueue[lang.Int]()
target := collections.NewArrayListByCapacity[lang.Int](10000)
fmt.Println("list", list)
go func() {
for i := 0; i < 1000000; i++ {
element, _ := list.Offer()
list.Offer()
//fmt.Println(offer)
if element != nil {
target.Add(element)
}
//if element != nil {
// target.Add(element)
//}
}
fmt.Println("target:", target)
}()
go func() {
for i := 0; i < 1000; i++ {
err = list.Push(i)
err = list.Push(lang.Int(i))
//fmt.Println(err)
}
time.Sleep(time.Second * 2)

17
util/Arrays.go Normal file
View File

@ -0,0 +1,17 @@
package util
import (
"github.com/tursom/GoCollections/collections"
"github.com/tursom/GoCollections/exceptions"
"github.com/tursom/GoCollections/lang"
)
func AsList[T lang.Object](arr []T) collections.List[T] {
return &arrayList[T]{arr}
}
func CheckedGet[T any](array []T, index int) (T, exceptions.Exception) {
return exceptions.CatchIndexOutOfBound(func() T {
return array[index]
}, exceptions.DefaultExceptionConfig().AddSkipStack(3))
}

61
util/arrayList.go Normal file
View File

@ -0,0 +1,61 @@
package util
import (
"github.com/tursom/GoCollections/collections"
"github.com/tursom/GoCollections/exceptions"
"github.com/tursom/GoCollections/lang"
)
type arrayList[T lang.Object] struct {
array []T
}
func (a *arrayList[T]) Iterator() collections.Iterator[T] {
return &arrayListIterator[T]{a.array, 0}
}
func (a *arrayList[T]) Size() int {
return len(a.array)
}
func (a *arrayList[T]) IsEmpty() bool {
return a.Size() == 0
}
func (a *arrayList[T]) Contains(element T) bool {
return collections.Contains[T](a, element)
}
func (a *arrayList[T]) ContainsAll(c collections.Collection[T]) bool {
return collections.ContainsAll[T](a, c)
}
func (a *arrayList[T]) Get(index int) (T, exceptions.Exception) {
return CheckedGet(a.array, index)
}
func (a *arrayList[T]) SubList(from, to int) collections.List[T] {
return &arrayList[T]{a.array[from:to]}
}
type arrayListIterator[T lang.Object] struct {
array []T
index int
}
func (a *arrayListIterator[T]) HasNext() bool {
return a.index < len(a.array)
}
func (a *arrayListIterator[T]) Next() (r T, err exceptions.Exception) {
defer func() {
r := recover()
if r != nil {
err = exceptions.NewNPE(r, nil)
}
}()
i := a.index
a.index++
r = a.array[i]
return
}

19
util/arrayList_test.go Normal file
View File

@ -0,0 +1,19 @@
package util
import (
"fmt"
"github.com/tursom/GoCollections/lang"
"testing"
)
func Test_arrayList_Get(t *testing.T) {
l := &arrayList[lang.Int]{[]lang.Int{1, 2}}
for i := 0; i < l.Size()+1; i++ {
r, err := l.Get(i)
if err != nil {
err.PrintStackTrace()
} else {
fmt.Println(r)
}
}
}