mirror of
https://github.com/tursom/GoCollections.git
synced 2025-03-26 02:30:08 +08:00
add basic package type
This commit is contained in:
parent
47dd188d72
commit
ca060c0304
@ -6,21 +6,18 @@ import (
|
||||
)
|
||||
|
||||
type ArrayList[T lang.Object] struct {
|
||||
lang.BaseObject
|
||||
array []T
|
||||
used int
|
||||
}
|
||||
|
||||
func NewArrayList[T lang.Object]() *ArrayList[T] {
|
||||
return &ArrayList[T]{
|
||||
make([]T, 16),
|
||||
0,
|
||||
}
|
||||
return NewArrayListByCapacity[T](16)
|
||||
}
|
||||
|
||||
func NewArrayListByCapacity[T lang.Object](cap int) *ArrayList[T] {
|
||||
return &ArrayList[T]{
|
||||
make([]T, cap),
|
||||
0,
|
||||
BaseObject: lang.NewBaseObject(),
|
||||
array: make([]T, 0, cap),
|
||||
}
|
||||
}
|
||||
|
||||
@ -33,7 +30,7 @@ func (a ArrayList[T]) Iterator() Iterator[T] {
|
||||
}
|
||||
|
||||
func (a ArrayList[T]) Size() int {
|
||||
return a.used
|
||||
return lang.Len(a.array)
|
||||
}
|
||||
|
||||
func (a ArrayList[T]) IsEmpty() bool {
|
||||
@ -49,20 +46,14 @@ func (a ArrayList[T]) ContainsAll(c Collection[T]) bool {
|
||||
}
|
||||
|
||||
func (a *ArrayList[T]) Add(element T) bool {
|
||||
if a.used >= len(a.array) {
|
||||
oldArray := a.array
|
||||
a.array = make([]T, a.used*2)
|
||||
copy(a.array, oldArray)
|
||||
}
|
||||
a.array[a.used] = element
|
||||
a.used++
|
||||
a.array = lang.Append(a.array, element)
|
||||
return true
|
||||
}
|
||||
|
||||
func (a ArrayList[T]) IndexOf(element T) int {
|
||||
for i := 0; i < a.used; i++ {
|
||||
for i := 0; i < a.Size(); i++ {
|
||||
if lang.Equals(element, a.array[i]) {
|
||||
return int(i)
|
||||
return i
|
||||
}
|
||||
}
|
||||
return -1
|
||||
@ -73,7 +64,7 @@ func (a *ArrayList[T]) Remove(element T) exceptions.Exception {
|
||||
if index < 0 {
|
||||
return exceptions.NewElementNotFoundException("", nil)
|
||||
} else {
|
||||
return a.RemoveAt(int(index))
|
||||
return a.RemoveAt(index)
|
||||
}
|
||||
}
|
||||
|
||||
@ -90,11 +81,11 @@ func (a *ArrayList[T]) RetainAll(c Collection[T]) bool {
|
||||
}
|
||||
|
||||
func (a *ArrayList[T]) Clear() {
|
||||
a.used = 0
|
||||
a.array = []T{}
|
||||
}
|
||||
|
||||
func (a ArrayList[T]) Get(index int) (T, exceptions.Exception) {
|
||||
if index >= a.used {
|
||||
if index >= a.Size() {
|
||||
return lang.Nil[T](), exceptions.NewIndexOutOfBound("", nil)
|
||||
} else {
|
||||
return a.array[index], nil
|
||||
@ -106,7 +97,7 @@ func (a ArrayList[T]) SubList(from, to int) List[T] {
|
||||
}
|
||||
|
||||
func (a *ArrayList[T]) Set(index int, element T) exceptions.Exception {
|
||||
if index >= a.used {
|
||||
if index >= a.Size() {
|
||||
return exceptions.NewIndexOutOfBound("", nil)
|
||||
}
|
||||
a.array[index] = element
|
||||
@ -114,47 +105,45 @@ func (a *ArrayList[T]) Set(index int, element T) exceptions.Exception {
|
||||
}
|
||||
|
||||
func (a *ArrayList[T]) AddAtIndex(index int, element T) bool {
|
||||
if !a.Add(element) {
|
||||
if index >= a.Size() {
|
||||
return false
|
||||
}
|
||||
|
||||
array := a.array
|
||||
for i := a.used - 1; i > index; i++ {
|
||||
array[i] = array[i-1]
|
||||
}
|
||||
array[index] = element
|
||||
a.used++
|
||||
a.array = lang.Append[T](array[:index], element)
|
||||
a.array = lang.Append[T](a.array, array[index:]...)
|
||||
return true
|
||||
}
|
||||
|
||||
func (a *ArrayList[T]) RemoveAt(index int) exceptions.Exception {
|
||||
if index >= a.used {
|
||||
if index >= a.Size() {
|
||||
return exceptions.NewIndexOutOfBound("", nil)
|
||||
}
|
||||
|
||||
array := a.array
|
||||
for i := index + 1; i < a.used; i++ {
|
||||
array[i-1] = array[i]
|
||||
}
|
||||
a.used--
|
||||
a.array = lang.Append[T](a.array[:index], a.array[index+1:]...)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *ArrayList[T]) SubMutableList(from, to int) MutableList[T] {
|
||||
panic("implement me")
|
||||
return NewMutableSubList[T](a, from, to)
|
||||
}
|
||||
|
||||
func (a *ArrayList[T]) MutableIterator() MutableIterator[T] {
|
||||
return &arrayListIterator[T]{a, 0}
|
||||
}
|
||||
|
||||
func (a *ArrayList[T]) RemoveLast() (T, exceptions.Exception) {
|
||||
v, _ := a.Get(a.Size() - 1)
|
||||
return v, a.RemoveAt(a.Size() - 1)
|
||||
}
|
||||
|
||||
type arrayListIterator[T lang.Object] struct {
|
||||
arrayList *ArrayList[T]
|
||||
index int
|
||||
}
|
||||
|
||||
func (a *arrayListIterator[T]) HasNext() bool {
|
||||
return a.index < a.arrayList.used
|
||||
return a.index < a.arrayList.Size()
|
||||
}
|
||||
|
||||
func (a *arrayListIterator[T]) Next() (T, exceptions.Exception) {
|
||||
|
58
collections/ArrayList_test.go
Normal file
58
collections/ArrayList_test.go
Normal file
@ -0,0 +1,58 @@
|
||||
package collections
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/tursom/GoCollections/exceptions"
|
||||
"github.com/tursom/GoCollections/lang"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestArrayListAdd(t *testing.T) {
|
||||
list := NewArrayList[lang.Int]()
|
||||
for i := 0; i < 10; i++ {
|
||||
list.Add(lang.Int(i))
|
||||
fmt.Println(list)
|
||||
}
|
||||
for i := 0; i < 10; i++ {
|
||||
list.RemoveLast()
|
||||
fmt.Println(list)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLinkedList(t *testing.T) {
|
||||
list := NewLinkedList[lang.Int]()
|
||||
for i := 0; i < 10; i++ {
|
||||
list.Add(lang.Int(i))
|
||||
fmt.Println(list)
|
||||
for j := 0; j <= i; j++ {
|
||||
//exceptions.Exec2r0[
|
||||
// func(func() (error, error, error)) (error, error),
|
||||
// func() (error, error, error),
|
||||
// error,
|
||||
//](
|
||||
exceptions.Exec2r0(
|
||||
//exceptions.Exec1r1,
|
||||
//exceptions.Exec0r2,
|
||||
exceptions.Exec1r1[func() (error, error, error), error, error],
|
||||
exceptions.Exec0r2[error, error, error],
|
||||
func() (error, error, error) {
|
||||
return nil, nil, nil
|
||||
},
|
||||
)
|
||||
fmt.Println(exceptions.Exec2r1((*LinkedList[lang.Int]).Get, list, j).AsInt())
|
||||
}
|
||||
}
|
||||
for i := 0; i < 10; i++ {
|
||||
list.RemoveLast()
|
||||
fmt.Println(list)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEqualsFunc(t *testing.T) {
|
||||
f := func() {}
|
||||
fmt.Println(equals(f, f))
|
||||
}
|
||||
|
||||
func equals(v1, v2 any) bool {
|
||||
return v1 == v2
|
||||
}
|
@ -68,6 +68,14 @@ type (
|
||||
}
|
||||
)
|
||||
|
||||
func ListGet[T lang.Object](list List[T], index int) T {
|
||||
get, err := list.Get(index)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return get
|
||||
}
|
||||
|
||||
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) {
|
||||
|
@ -8,10 +8,11 @@ import (
|
||||
)
|
||||
|
||||
type ConcurrentLinkedQueue[T lang.Object] struct {
|
||||
lang.BaseObject
|
||||
head *concurrentLinkedQueueNode[T]
|
||||
}
|
||||
|
||||
func (c ConcurrentLinkedQueue[T]) String() string {
|
||||
func (c *ConcurrentLinkedQueue[T]) String() string {
|
||||
return String[T](c)
|
||||
}
|
||||
|
||||
@ -30,10 +31,10 @@ func NewConcurrentLinkedQueue[T lang.Object]() *ConcurrentLinkedQueue[T] {
|
||||
head := &concurrentLinkedQueueNode[T]{}
|
||||
head.prev = head
|
||||
head.next = head
|
||||
return &ConcurrentLinkedQueue[T]{head}
|
||||
return &ConcurrentLinkedQueue[T]{lang.NewBaseObject(), head}
|
||||
}
|
||||
|
||||
func (c ConcurrentLinkedQueue[T]) Iterator() Iterator[T] {
|
||||
func (c *ConcurrentLinkedQueue[T]) Iterator() Iterator[T] {
|
||||
return c.MutableIterator()
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,7 @@ import (
|
||||
)
|
||||
|
||||
type ConcurrentLinkedStack[T any] struct {
|
||||
lang.BaseObject
|
||||
head *concurrentLinkedStackNode[T]
|
||||
p *unsafe.Pointer
|
||||
}
|
||||
@ -28,7 +29,7 @@ type concurrentLinkedStackIterator[T any] struct {
|
||||
|
||||
func NewConcurrentLinkedStack[T any]() *ConcurrentLinkedStack[T] {
|
||||
head := &concurrentLinkedStackNode[T]{}
|
||||
return &ConcurrentLinkedStack[T]{head, (*unsafe.Pointer)(unsafe.Pointer(&head.next))}
|
||||
return &ConcurrentLinkedStack[T]{lang.NewBaseObject(), head, (*unsafe.Pointer)(unsafe.Pointer(&head.next))}
|
||||
}
|
||||
|
||||
func (c ConcurrentLinkedStack[T]) Iterator() Iterator[T] {
|
||||
|
6
collections/GoMap.go
Normal file
6
collections/GoMap.go
Normal file
@ -0,0 +1,6 @@
|
||||
package collections
|
||||
|
||||
import "github.com/tursom/GoCollections/lang"
|
||||
|
||||
type GoMap[K lang.Object, V any] struct {
|
||||
}
|
15
collections/Hash.go
Normal file
15
collections/Hash.go
Normal file
@ -0,0 +1,15 @@
|
||||
package collections
|
||||
|
||||
import (
|
||||
"github.com/tursom/GoCollections/exceptions"
|
||||
"github.com/tursom/GoCollections/lang"
|
||||
)
|
||||
|
||||
func HashIterable[E lang.Object](iterable Iterable[E]) int32 {
|
||||
hashCode := int32(0)
|
||||
_ = Loop(iterable, func(element E) exceptions.Exception {
|
||||
hashCode = hashCode*31 ^ element.HashCode()
|
||||
return nil
|
||||
})
|
||||
return hashCode
|
||||
}
|
15
collections/Hash_test.go
Normal file
15
collections/Hash_test.go
Normal file
@ -0,0 +1,15 @@
|
||||
package collections
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/tursom/GoCollections/lang"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestHashIterable(t *testing.T) {
|
||||
list := NewArrayList[lang.String]()
|
||||
for i := 0; i < 201; i++ {
|
||||
list.Add(lang.Int(i).ToString())
|
||||
}
|
||||
fmt.Println(HashIterable[lang.String](list))
|
||||
}
|
@ -7,6 +7,7 @@ import (
|
||||
|
||||
type (
|
||||
LinkedList[T lang.Object] struct {
|
||||
lang.BaseObject
|
||||
head *linkedListNode[T]
|
||||
size int
|
||||
}
|
||||
@ -14,9 +15,13 @@ type (
|
||||
prev, next *linkedListNode[T]
|
||||
value T
|
||||
}
|
||||
linkedListIterator[T lang.Object] struct {
|
||||
list *LinkedList[T]
|
||||
node, head *linkedListNode[T]
|
||||
}
|
||||
)
|
||||
|
||||
func (l LinkedList[T]) String() string {
|
||||
func (l *LinkedList[T]) String() string {
|
||||
return String[T](l)
|
||||
}
|
||||
|
||||
@ -24,23 +29,23 @@ func NewLinkedList[T lang.Object]() *LinkedList[T] {
|
||||
tail := &linkedListNode[T]{}
|
||||
tail.prev = tail
|
||||
tail.next = tail
|
||||
return &LinkedList[T]{tail, 0}
|
||||
return &LinkedList[T]{lang.NewBaseObject(), tail, 0}
|
||||
}
|
||||
|
||||
func (l LinkedList[T]) Size() int {
|
||||
func (l *LinkedList[T]) Size() int {
|
||||
return l.size
|
||||
}
|
||||
|
||||
func (l LinkedList[T]) IsEmpty() bool {
|
||||
func (l *LinkedList[T]) IsEmpty() bool {
|
||||
return l.size == 0
|
||||
}
|
||||
|
||||
func (l LinkedList[T]) Contains(element T) bool {
|
||||
return Contains[T](&l, element)
|
||||
func (l *LinkedList[T]) Contains(element T) bool {
|
||||
return Contains[T](l, element)
|
||||
}
|
||||
|
||||
func (l LinkedList[T]) ContainsAll(c Collection[T]) bool {
|
||||
return ContainsAll[T](&l, c)
|
||||
func (l *LinkedList[T]) ContainsAll(c Collection[T]) bool {
|
||||
return ContainsAll[T](l, c)
|
||||
}
|
||||
|
||||
func (l *LinkedList[T]) Add(element T) bool {
|
||||
@ -83,7 +88,7 @@ func (l *LinkedList[T]) Clear() {
|
||||
l.size = 0
|
||||
}
|
||||
|
||||
func (l LinkedList[T]) SubList(from, to int) List[T] {
|
||||
func (l *LinkedList[T]) SubList(from, to int) List[T] {
|
||||
return NewSubList[T](l, from, to)
|
||||
}
|
||||
|
||||
@ -125,24 +130,52 @@ func (l *LinkedList[T]) RemoveAt(index int) exceptions.Exception {
|
||||
}
|
||||
return exceptions.NewIndexOutOfBound("", nil)
|
||||
}
|
||||
func (l *LinkedList[T]) RemoveLast() (T, exceptions.Exception) {
|
||||
if l.head.next == l.head {
|
||||
return lang.Nil[T](), exceptions.NewIndexOutOfBound("list is empty", nil)
|
||||
}
|
||||
return l.head.prev.remove(), nil
|
||||
}
|
||||
|
||||
func (l *LinkedList[T]) SubMutableList(from, to int) MutableList[T] {
|
||||
return NewMutableSubList[T](l, from, to)
|
||||
}
|
||||
|
||||
func (l LinkedList[T]) Get(index int) (T, exceptions.Exception) {
|
||||
node := l.head
|
||||
for node != l.head {
|
||||
func (l *LinkedList[T]) Get(index int) (T, exceptions.Exception) {
|
||||
if index < l.size/2 {
|
||||
return loopLinkedListNodeUp[T](l.head, index)
|
||||
} else {
|
||||
return loopLinkedListNodeDown[T](l.head, l.size-index-1)
|
||||
}
|
||||
}
|
||||
|
||||
func loopLinkedListNodeUp[T lang.Object](head *linkedListNode[T], index int) (T, exceptions.Exception) {
|
||||
node := head.next
|
||||
for node != head {
|
||||
if index == 0 {
|
||||
return node.value, nil
|
||||
}
|
||||
index--
|
||||
node = node.next
|
||||
}
|
||||
|
||||
return lang.Nil[T](), exceptions.NewIndexOutOfBound("", nil)
|
||||
}
|
||||
|
||||
func (l LinkedList[T]) Iterator() Iterator[T] {
|
||||
func loopLinkedListNodeDown[T lang.Object](head *linkedListNode[T], index int) (T, exceptions.Exception) {
|
||||
node := head.prev
|
||||
for node != head {
|
||||
if index == 0 {
|
||||
return node.value, nil
|
||||
}
|
||||
index--
|
||||
node = node.prev
|
||||
}
|
||||
|
||||
return lang.Nil[T](), exceptions.NewIndexOutOfBound("", nil)
|
||||
}
|
||||
|
||||
func (l *LinkedList[T]) Iterator() Iterator[T] {
|
||||
return l.MutableIterator()
|
||||
}
|
||||
|
||||
@ -150,11 +183,6 @@ func (l *LinkedList[T]) MutableIterator() MutableIterator[T] {
|
||||
return &linkedListIterator[T]{l, l.head.next, l.head}
|
||||
}
|
||||
|
||||
type linkedListIterator[T lang.Object] struct {
|
||||
list *LinkedList[T]
|
||||
node, head *linkedListNode[T]
|
||||
}
|
||||
|
||||
func (l *linkedListIterator[T]) HasNext() bool {
|
||||
return l.node != l.head
|
||||
}
|
||||
@ -176,7 +204,8 @@ func (l *linkedListIterator[T]) Remove() exceptions.Exception {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l *linkedListNode[T]) remove() {
|
||||
func (l *linkedListNode[T]) remove() T {
|
||||
l.next.prev = l.prev
|
||||
l.prev.next = l.next
|
||||
return l.value
|
||||
}
|
||||
|
162
collections/LockedMutableList.go
Normal file
162
collections/LockedMutableList.go
Normal file
@ -0,0 +1,162 @@
|
||||
package collections
|
||||
|
||||
import (
|
||||
"github.com/tursom/GoCollections/concurrent"
|
||||
"github.com/tursom/GoCollections/exceptions"
|
||||
"github.com/tursom/GoCollections/lang"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type (
|
||||
LockedMutableList[T lang.Object] struct {
|
||||
list MutableList[T]
|
||||
lock concurrent.RWLock
|
||||
}
|
||||
lockedMutableListIterator[T lang.Object] struct {
|
||||
iterator MutableIterator[T]
|
||||
lock concurrent.RWLock
|
||||
}
|
||||
)
|
||||
|
||||
func MutableListWithLock[T lang.Object](list MutableList[T]) MutableList[T] {
|
||||
return &LockedMutableList[T]{
|
||||
list: list,
|
||||
lock: &sync.RWMutex{},
|
||||
}
|
||||
}
|
||||
|
||||
func (l *LockedMutableList[T]) String() string {
|
||||
return String[T](l)
|
||||
}
|
||||
|
||||
func (l *LockedMutableList[T]) Iterator() Iterator[T] {
|
||||
return l.MutableIterator()
|
||||
}
|
||||
|
||||
func (l *LockedMutableList[T]) Size() int {
|
||||
l.lock.RLock()
|
||||
defer l.lock.RUnlock()
|
||||
|
||||
return l.list.Size()
|
||||
}
|
||||
|
||||
func (l *LockedMutableList[T]) IsEmpty() bool {
|
||||
return l.Size() == 0
|
||||
}
|
||||
|
||||
func (l *LockedMutableList[T]) Contains(element T) bool {
|
||||
l.lock.RLock()
|
||||
defer l.lock.RUnlock()
|
||||
|
||||
return l.list.Contains(element)
|
||||
}
|
||||
|
||||
func (l *LockedMutableList[T]) ContainsAll(c Collection[T]) bool {
|
||||
l.lock.RLock()
|
||||
defer l.lock.RUnlock()
|
||||
|
||||
return l.list.ContainsAll(c)
|
||||
}
|
||||
|
||||
func (l *LockedMutableList[T]) MutableIterator() MutableIterator[T] {
|
||||
return &lockedMutableListIterator[T]{l.list.MutableIterator(), l.lock}
|
||||
}
|
||||
|
||||
func (l *LockedMutableList[T]) Add(element T) bool {
|
||||
l.lock.Lock()
|
||||
defer l.lock.Unlock()
|
||||
|
||||
return l.list.Add(element)
|
||||
}
|
||||
|
||||
func (l *LockedMutableList[T]) Remove(element T) exceptions.Exception {
|
||||
l.lock.Lock()
|
||||
defer l.lock.Unlock()
|
||||
|
||||
return l.list.Remove(element)
|
||||
}
|
||||
|
||||
func (l *LockedMutableList[T]) AddAll(c Collection[T]) bool {
|
||||
l.lock.Lock()
|
||||
defer l.lock.Unlock()
|
||||
|
||||
return l.list.AddAll(c)
|
||||
}
|
||||
|
||||
func (l *LockedMutableList[T]) RemoveAll(c Collection[T]) bool {
|
||||
l.lock.Lock()
|
||||
defer l.lock.Unlock()
|
||||
|
||||
return l.list.RemoveAll(c)
|
||||
}
|
||||
|
||||
func (l *LockedMutableList[T]) RetainAll(c Collection[T]) bool {
|
||||
l.lock.Lock()
|
||||
defer l.lock.Unlock()
|
||||
|
||||
return l.list.RetainAll(c)
|
||||
}
|
||||
|
||||
func (l *LockedMutableList[T]) Clear() {
|
||||
l.lock.Lock()
|
||||
defer l.lock.Unlock()
|
||||
|
||||
l.list.Clear()
|
||||
}
|
||||
|
||||
func (l *LockedMutableList[T]) Get(index int) (T, exceptions.Exception) {
|
||||
l.lock.RLock()
|
||||
defer l.lock.RUnlock()
|
||||
|
||||
return l.list.Get(index)
|
||||
}
|
||||
|
||||
func (l *LockedMutableList[T]) SubList(from, to int) List[T] {
|
||||
return l.SubMutableList(from, to)
|
||||
}
|
||||
|
||||
func (l *LockedMutableList[T]) Set(index int, element T) exceptions.Exception {
|
||||
l.lock.Lock()
|
||||
defer l.lock.Unlock()
|
||||
|
||||
return l.list.Set(index, element)
|
||||
}
|
||||
|
||||
func (l *LockedMutableList[T]) AddAtIndex(index int, element T) bool {
|
||||
l.lock.Lock()
|
||||
defer l.lock.Unlock()
|
||||
|
||||
return l.list.AddAtIndex(index, element)
|
||||
}
|
||||
|
||||
func (l *LockedMutableList[T]) RemoveAt(index int) exceptions.Exception {
|
||||
l.lock.Lock()
|
||||
defer l.lock.Unlock()
|
||||
|
||||
return l.list.RemoveAt(index)
|
||||
}
|
||||
|
||||
func (l *LockedMutableList[T]) SubMutableList(from, to int) MutableList[T] {
|
||||
return &LockedMutableList[T]{l.list.SubMutableList(from, to), l.lock}
|
||||
}
|
||||
|
||||
func (l *lockedMutableListIterator[T]) HasNext() bool {
|
||||
l.lock.RLock()
|
||||
defer l.lock.RUnlock()
|
||||
|
||||
return l.iterator.HasNext()
|
||||
}
|
||||
|
||||
func (l *lockedMutableListIterator[T]) Next() (T, exceptions.Exception) {
|
||||
l.lock.RLock()
|
||||
defer l.lock.RUnlock()
|
||||
|
||||
return l.iterator.Next()
|
||||
}
|
||||
|
||||
func (l *lockedMutableListIterator[T]) Remove() exceptions.Exception {
|
||||
l.lock.Lock()
|
||||
defer l.lock.Unlock()
|
||||
|
||||
return l.iterator.Remove()
|
||||
}
|
11
collections/Map.go
Normal file
11
collections/Map.go
Normal file
@ -0,0 +1,11 @@
|
||||
package collections
|
||||
|
||||
import (
|
||||
"github.com/tursom/GoCollections/exceptions"
|
||||
"github.com/tursom/GoCollections/lang"
|
||||
)
|
||||
|
||||
type Map[K lang.Object, V any] interface {
|
||||
Put(k K, v V) (bool, exceptions.Exception)
|
||||
Get(k K) (V, exceptions.Exception)
|
||||
}
|
@ -6,12 +6,13 @@ import (
|
||||
)
|
||||
|
||||
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) MutableList[T] {
|
||||
return &MutableSubList[T]{list, from, to}
|
||||
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] {
|
||||
|
@ -6,12 +6,13 @@ import (
|
||||
)
|
||||
|
||||
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) List[T] {
|
||||
return &SubList[T]{list, from, to}
|
||||
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] {
|
||||
|
14
concurrent/Lock.go
Normal file
14
concurrent/Lock.go
Normal file
@ -0,0 +1,14 @@
|
||||
package concurrent
|
||||
|
||||
type (
|
||||
Lock interface {
|
||||
Lock()
|
||||
Unlock()
|
||||
}
|
||||
RWLock interface {
|
||||
Lock()
|
||||
Unlock()
|
||||
RLock()
|
||||
RUnlock()
|
||||
}
|
||||
)
|
26
concurrent/ReentrantLock.go
Normal file
26
concurrent/ReentrantLock.go
Normal file
@ -0,0 +1,26 @@
|
||||
package concurrent
|
||||
|
||||
import "sync"
|
||||
|
||||
type ReentrantLock struct {
|
||||
sync.Mutex
|
||||
cnt int32
|
||||
}
|
||||
|
||||
func (l *ReentrantLock) Lock() {
|
||||
defer func() {
|
||||
r := recover()
|
||||
if r != nil {
|
||||
l.cnt++
|
||||
}
|
||||
}()
|
||||
|
||||
l.Mutex.Lock()
|
||||
}
|
||||
|
||||
func (l *ReentrantLock) Unlock() {
|
||||
l.cnt--
|
||||
if l.cnt == 0 {
|
||||
l.Mutex.Unlock()
|
||||
}
|
||||
}
|
11
concurrent/ReentrantLock_test.go
Normal file
11
concurrent/ReentrantLock_test.go
Normal file
@ -0,0 +1,11 @@
|
||||
package concurrent
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestMutex(t *testing.T) {
|
||||
mutex := &ReentrantLock{}
|
||||
mutex.Lock()
|
||||
mutex.Lock()
|
||||
}
|
@ -4,7 +4,7 @@ type ElementNotFoundException struct {
|
||||
RuntimeException
|
||||
}
|
||||
|
||||
func NewElementNotFoundException(message interface{}, config *ExceptionConfig) *ElementNotFoundException {
|
||||
func NewElementNotFoundException(message any, config *ExceptionConfig) *ElementNotFoundException {
|
||||
config.AddSkipStack(1)
|
||||
return &ElementNotFoundException{
|
||||
NewRuntimeException(
|
||||
|
@ -57,7 +57,7 @@ func BuildStackTrace(builder *strings.Builder, e Exception, exceptionMsg string)
|
||||
|
||||
func Try[R any](
|
||||
f func() (ret R, err Exception),
|
||||
catch func(panic interface{}) (ret R, err Exception),
|
||||
catch func(panic any) (ret R, err Exception),
|
||||
) (ret R, err Exception) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
@ -95,7 +95,7 @@ func Package(err error) Exception {
|
||||
return NewRuntimeException(err, "", DefaultExceptionConfig().SetCause(err))
|
||||
}
|
||||
|
||||
func PackageAny(err interface{}) Exception {
|
||||
func PackageAny(err any) Exception {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
@ -107,7 +107,7 @@ func PackageAny(err interface{}) Exception {
|
||||
}
|
||||
}
|
||||
|
||||
func PackagePanic(panic interface{}, exceptionMessage string) Exception {
|
||||
func PackagePanic(panic any, exceptionMessage string) Exception {
|
||||
if panic == nil {
|
||||
return nil
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ package exceptions
|
||||
type ExceptionConfig struct {
|
||||
SkipStack int
|
||||
GetStackTrace bool
|
||||
Cause interface{}
|
||||
Cause any
|
||||
}
|
||||
|
||||
func DefaultExceptionConfig() *ExceptionConfig {
|
||||
@ -30,7 +30,7 @@ func (c *ExceptionConfig) SetGetStackTrace(getStackTrace bool) *ExceptionConfig
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *ExceptionConfig) SetCause(cause interface{}) *ExceptionConfig {
|
||||
func (c *ExceptionConfig) SetCause(cause any) *ExceptionConfig {
|
||||
if c == nil {
|
||||
return DefaultExceptionConfig().SetCause(cause)
|
||||
}
|
||||
|
93
exceptions/Exec.go
Normal file
93
exceptions/Exec.go
Normal file
@ -0,0 +1,93 @@
|
||||
package exceptions
|
||||
|
||||
func Exec0r0[E error](f func() E) {
|
||||
err := f()
|
||||
if error(err) != nil {
|
||||
panic(Package(err))
|
||||
}
|
||||
}
|
||||
|
||||
func Exec0r1[R1 any, E error](f func() (R1, E)) R1 {
|
||||
r, err := f()
|
||||
if error(err) != nil {
|
||||
panic(Package(err))
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func Exec0r2[R1, R2 any, E error](f func() (R1, R2, E)) (R1, R2) {
|
||||
r1, r2, err := f()
|
||||
if error(err) != nil {
|
||||
panic(Package(err))
|
||||
}
|
||||
return r1, r2
|
||||
}
|
||||
|
||||
func Exec1r0[A1 any, E error](f func(A1) E, a1 A1) {
|
||||
err := f(a1)
|
||||
if error(err) != nil {
|
||||
panic(Package(err))
|
||||
}
|
||||
}
|
||||
|
||||
func Exec1r1[A1, R1 any, E error](f func(A1) (R1, E), a1 A1) R1 {
|
||||
r, err := f(a1)
|
||||
if error(err) != nil {
|
||||
panic(Package(err))
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func Exec1r2[A1, R1, R2 any, E error](f func(A1) (R1, R2, E), a1 A1) (R1, R2) {
|
||||
r1, r2, err := f(a1)
|
||||
if error(err) != nil {
|
||||
panic(Package(err))
|
||||
}
|
||||
return r1, r2
|
||||
}
|
||||
|
||||
func Exec2r0[A1, A2 any, E error](f func(A1, A2) E, a1 A1, a2 A2) {
|
||||
err := f(a1, a2)
|
||||
if error(err) != nil {
|
||||
panic(Package(err))
|
||||
}
|
||||
}
|
||||
|
||||
func Exec2r1[A1, A2, R1 any, E error](f func(A1, A2) (R1, E), a1 A1, a2 A2) R1 {
|
||||
r, err := f(a1, a2)
|
||||
if error(err) != nil {
|
||||
panic(Package(err))
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func Exec2r2[A1, A2, R1, R2 any, E error](f func(A1, A2) (R1, R2, E), a1 A1, a2 A2) (R1, R2) {
|
||||
r1, r2, err := f(a1, a2)
|
||||
if error(err) != nil {
|
||||
panic(Package(err))
|
||||
}
|
||||
return r1, r2
|
||||
}
|
||||
|
||||
func Exec3r0[A1, A2, A3 any, E error](f func(A1, A2, A3) E, a1 A1, a2 A2, a3 A3) {
|
||||
err := f(a1, a2, a3)
|
||||
if error(err) != nil {
|
||||
panic(Package(err))
|
||||
}
|
||||
}
|
||||
|
||||
func Exec3r1[A1, A2, A3, R1 any, E error](f func(A1, A2, A3) (R1, E), a1 A1, a2 A2, a3 A3) R1 {
|
||||
r, err := f(a1, a2, a3)
|
||||
if error(err) != nil {
|
||||
panic(Package(err))
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func Exec3r2[A1, A2, A3, R1, R2 any, E error](f func(A1, A2, A3) (R1, R2, E), a1 A1, a2 A2, a3 A3) (R1, R2) {
|
||||
r1, r2, err := f(a1, a2, a3)
|
||||
if error(err) != nil {
|
||||
panic(Package(err))
|
||||
}
|
||||
return r1, r2
|
||||
}
|
@ -4,7 +4,7 @@ type IndexOutOfBound struct {
|
||||
RuntimeException
|
||||
}
|
||||
|
||||
func NewIndexOutOfBound(message interface{}, config *ExceptionConfig) *IndexOutOfBound {
|
||||
func NewIndexOutOfBound(message any, config *ExceptionConfig) *IndexOutOfBound {
|
||||
config.AddSkipStack(1)
|
||||
return &IndexOutOfBound{
|
||||
NewRuntimeException(
|
||||
|
@ -4,7 +4,7 @@ type NPE struct {
|
||||
RuntimeException
|
||||
}
|
||||
|
||||
func NewNPE(message interface{}, config *ExceptionConfig) *NPE {
|
||||
func NewNPE(message any, config *ExceptionConfig) *NPE {
|
||||
config.AddSkipStack(1)
|
||||
return &NPE{
|
||||
NewRuntimeException(
|
||||
|
@ -4,7 +4,7 @@ type OperationNotSupportedException struct {
|
||||
RuntimeException
|
||||
}
|
||||
|
||||
func NewOperationNotSupportedException(message interface{}, config *ExceptionConfig) *OperationNotSupportedException {
|
||||
func NewOperationNotSupportedException(message any, config *ExceptionConfig) *OperationNotSupportedException {
|
||||
config.AddSkipStack(1)
|
||||
return &OperationNotSupportedException{
|
||||
NewRuntimeException(
|
||||
|
@ -2,10 +2,10 @@ package exceptions
|
||||
|
||||
type PackageException struct {
|
||||
RuntimeException
|
||||
err interface{}
|
||||
err any
|
||||
}
|
||||
|
||||
func NewPackageException(err interface{}, exceptionMessage string, config *ExceptionConfig) *PackageException {
|
||||
func NewPackageException(err any, exceptionMessage string, config *ExceptionConfig) *PackageException {
|
||||
config.AddSkipStack(1)
|
||||
return &PackageException{
|
||||
RuntimeException: NewRuntimeException(err, exceptionMessage, config),
|
||||
@ -13,11 +13,11 @@ func NewPackageException(err interface{}, exceptionMessage string, config *Excep
|
||||
}
|
||||
}
|
||||
|
||||
func (p *PackageException) Err() interface{} {
|
||||
func (p *PackageException) Err() any {
|
||||
return p.err
|
||||
}
|
||||
|
||||
func UnpackException(err interface{}) interface{} {
|
||||
func UnpackException(err any) any {
|
||||
for err != nil {
|
||||
switch err.(type) {
|
||||
case *PackageException:
|
||||
|
@ -2,19 +2,21 @@ package exceptions
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/tursom/GoCollections/lang"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type RuntimeException struct {
|
||||
lang.BaseObject
|
||||
message string
|
||||
exceptionMessage string
|
||||
stackTrace []StackTrace
|
||||
cause Exception
|
||||
}
|
||||
|
||||
func NewRuntimeException(message interface{}, exceptionMessage string, config *ExceptionConfig) RuntimeException {
|
||||
func NewRuntimeException(message any, exceptionMessage string, config *ExceptionConfig) RuntimeException {
|
||||
if config == nil {
|
||||
config = DefaultExceptionConfig()
|
||||
}
|
||||
@ -40,6 +42,7 @@ func NewRuntimeException(message interface{}, exceptionMessage string, config *E
|
||||
}
|
||||
|
||||
return RuntimeException{
|
||||
BaseObject: lang.NewBaseObject(),
|
||||
message: fmt.Sprint(message),
|
||||
exceptionMessage: exceptionMessage,
|
||||
stackTrace: stackTrace,
|
||||
|
35
lang/Complex128.go
Normal file
35
lang/Complex128.go
Normal file
@ -0,0 +1,35 @@
|
||||
package lang
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type Complex128 complex128
|
||||
|
||||
func (i Complex128) AsComplex128() complex128 {
|
||||
return complex128(i)
|
||||
}
|
||||
|
||||
func (i Complex128) String() string {
|
||||
return fmt.Sprint(complex64(i))
|
||||
}
|
||||
|
||||
func (i Complex128) AsObject() Object {
|
||||
return i
|
||||
}
|
||||
|
||||
func (i Complex128) Equals(e Object) bool {
|
||||
i2, ok := e.(Complex128)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return i == i2
|
||||
}
|
||||
|
||||
func (i Complex128) ToString() String {
|
||||
return NewString(i.String())
|
||||
}
|
||||
|
||||
func (i Complex128) HashCode() int32 {
|
||||
return Float64(real(complex64(i))).HashCode() ^ Float64(imag(complex64(i))).HashCode()
|
||||
}
|
35
lang/Complex64.go
Normal file
35
lang/Complex64.go
Normal file
@ -0,0 +1,35 @@
|
||||
package lang
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type Complex64 complex64
|
||||
|
||||
func (i Complex64) AsComplex64() complex64 {
|
||||
return complex64(i)
|
||||
}
|
||||
|
||||
func (i Complex64) String() string {
|
||||
return fmt.Sprint(complex64(i))
|
||||
}
|
||||
|
||||
func (i Complex64) AsObject() Object {
|
||||
return i
|
||||
}
|
||||
|
||||
func (i Complex64) Equals(e Object) bool {
|
||||
i2, ok := e.(Complex64)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return i == i2
|
||||
}
|
||||
|
||||
func (i Complex64) ToString() String {
|
||||
return NewString(i.String())
|
||||
}
|
||||
|
||||
func (i Complex64) HashCode() int32 {
|
||||
return Float32(real(complex64(i))).HashCode() ^ Float32(imag(complex64(i))).HashCode()
|
||||
}
|
46
lang/Float32.go
Normal file
46
lang/Float32.go
Normal file
@ -0,0 +1,46 @@
|
||||
package lang
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type Float32 float32
|
||||
|
||||
func (i Float32) AsFloat32() float32 {
|
||||
return float32(i)
|
||||
}
|
||||
|
||||
func (i Float32) String() string {
|
||||
return fmt.Sprint(float32(i))
|
||||
}
|
||||
|
||||
func (i Float32) AsObject() Object {
|
||||
return i
|
||||
}
|
||||
|
||||
func (i Float32) Equals(e Object) bool {
|
||||
i2, ok := e.(Float32)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return i == i2
|
||||
}
|
||||
|
||||
func (i Float32) ToString() String {
|
||||
return NewString(i.String())
|
||||
}
|
||||
|
||||
func (i Float32) HashCode() int32 {
|
||||
return Hash32(&i)
|
||||
}
|
||||
|
||||
func (i Float32) Compare(t Float32) int {
|
||||
switch {
|
||||
case i > t:
|
||||
return 1
|
||||
case i == t:
|
||||
return 0
|
||||
default:
|
||||
return -1
|
||||
}
|
||||
}
|
46
lang/Float64.go
Normal file
46
lang/Float64.go
Normal file
@ -0,0 +1,46 @@
|
||||
package lang
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type Float64 float64
|
||||
|
||||
func (i Float64) AsFloat64() float64 {
|
||||
return float64(i)
|
||||
}
|
||||
|
||||
func (i Float64) String() string {
|
||||
return fmt.Sprint(float64(i))
|
||||
}
|
||||
|
||||
func (i Float64) AsObject() Object {
|
||||
return i
|
||||
}
|
||||
|
||||
func (i Float64) Equals(e Object) bool {
|
||||
i2, ok := e.(Float64)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return i == i2
|
||||
}
|
||||
|
||||
func (i Float64) ToString() String {
|
||||
return NewString(i.String())
|
||||
}
|
||||
|
||||
func (i Float64) HashCode() int32 {
|
||||
return Hash64(&i)
|
||||
}
|
||||
|
||||
func (i Float64) Compare(t Float64) int {
|
||||
switch {
|
||||
case i > t:
|
||||
return 1
|
||||
case i == t:
|
||||
return 0
|
||||
default:
|
||||
return -1
|
||||
}
|
||||
}
|
41
lang/Hash.go
Normal file
41
lang/Hash.go
Normal file
@ -0,0 +1,41 @@
|
||||
package lang
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
//goland:noinspection GoVetUnsafePointer
|
||||
func HashAddr[V any](v *V) int32 {
|
||||
p := uintptr(unsafe.Pointer(v))
|
||||
remain := int32(unsafe.Sizeof(*v))
|
||||
hash := int32(0)
|
||||
for remain-4 >= 0 {
|
||||
remain -= 4
|
||||
hash = hash*31 ^ *(*int32)(unsafe.Pointer(p))
|
||||
p += 4
|
||||
}
|
||||
for remain > 0 {
|
||||
hash = hash*31 ^ int32(*(*int8)(unsafe.Pointer(p)))
|
||||
p++
|
||||
remain--
|
||||
}
|
||||
|
||||
return hash
|
||||
}
|
||||
|
||||
func Hash32[T any](p *T) int32 {
|
||||
return *(*int32)(unsafe.Pointer(p))
|
||||
}
|
||||
|
||||
func Hash64[T any](p *T) int32 {
|
||||
i := *(*int64)(unsafe.Pointer(p))
|
||||
return int32(i)*31 ^ int32(i>>32)
|
||||
}
|
||||
|
||||
func HashString(str string) int32 {
|
||||
hashCode := int32(0)
|
||||
for _, r := range str {
|
||||
hashCode = 31*hashCode + r
|
||||
}
|
||||
return hashCode
|
||||
}
|
15
lang/Hash_test.go
Normal file
15
lang/Hash_test.go
Normal file
@ -0,0 +1,15 @@
|
||||
package lang
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestHashAddr(t *testing.T) {
|
||||
str := "test"
|
||||
fmt.Println(HashAddr(&str))
|
||||
}
|
||||
|
||||
func TestHashString(t *testing.T) {
|
||||
fmt.Println(HashString("testwerwefdcsd"))
|
||||
}
|
33
lang/Int.go
33
lang/Int.go
@ -1,7 +1,17 @@
|
||||
package lang
|
||||
|
||||
import "strconv"
|
||||
|
||||
type Int int
|
||||
|
||||
func (i Int) AsInt() int {
|
||||
return int(i)
|
||||
}
|
||||
|
||||
func (i Int) String() string {
|
||||
return strconv.Itoa(int(i))
|
||||
}
|
||||
|
||||
func (i Int) Equals(e Object) bool {
|
||||
i2, ok := e.(Int)
|
||||
if !ok {
|
||||
@ -10,6 +20,25 @@ func (i Int) Equals(e Object) bool {
|
||||
return i == i2
|
||||
}
|
||||
|
||||
func (i Int) Compare(t Int) int {
|
||||
return int(t - i)
|
||||
func (i Int) AsObject() Object {
|
||||
return i
|
||||
}
|
||||
|
||||
func (i Int) ToString() String {
|
||||
return NewString(i.String())
|
||||
}
|
||||
|
||||
func (i Int) HashCode() int32 {
|
||||
return Int64(i).HashCode()
|
||||
}
|
||||
|
||||
func (i Int) Compare(t Int) int {
|
||||
switch {
|
||||
case i > t:
|
||||
return 1
|
||||
case i == t:
|
||||
return 0
|
||||
default:
|
||||
return -1
|
||||
}
|
||||
}
|
||||
|
44
lang/Int16.go
Normal file
44
lang/Int16.go
Normal file
@ -0,0 +1,44 @@
|
||||
package lang
|
||||
|
||||
import "strconv"
|
||||
|
||||
type Int16 int16
|
||||
|
||||
func (i Int16) AsInt16() int16 {
|
||||
return int16(i)
|
||||
}
|
||||
|
||||
func (i Int16) String() string {
|
||||
return strconv.FormatInt(int64(i), 10)
|
||||
}
|
||||
|
||||
func (i Int16) AsObject() Object {
|
||||
return i
|
||||
}
|
||||
|
||||
func (i Int16) Equals(e Object) bool {
|
||||
i2, ok := e.(Int16)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return i == i2
|
||||
}
|
||||
|
||||
func (i Int16) ToString() String {
|
||||
return NewString(i.String())
|
||||
}
|
||||
|
||||
func (i Int16) HashCode() int32 {
|
||||
return int32(i)
|
||||
}
|
||||
|
||||
func (i Int16) Compare(t Int16) int {
|
||||
switch {
|
||||
case i > t:
|
||||
return 1
|
||||
case i == t:
|
||||
return 0
|
||||
default:
|
||||
return -1
|
||||
}
|
||||
}
|
46
lang/Int32.go
Normal file
46
lang/Int32.go
Normal file
@ -0,0 +1,46 @@
|
||||
package lang
|
||||
|
||||
import "strconv"
|
||||
|
||||
type Int32 int32
|
||||
|
||||
type Rune = Int32
|
||||
|
||||
func (i Int32) AsInt32() int32 {
|
||||
return int32(i)
|
||||
}
|
||||
|
||||
func (i Int32) String() string {
|
||||
return strconv.FormatInt(int64(i), 10)
|
||||
}
|
||||
|
||||
func (i Int32) AsObject() Object {
|
||||
return i
|
||||
}
|
||||
|
||||
func (i Int32) Equals(e Object) bool {
|
||||
i2, ok := e.(Int32)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return i == i2
|
||||
}
|
||||
|
||||
func (i Int32) ToString() String {
|
||||
return NewString(i.String())
|
||||
}
|
||||
|
||||
func (i Int32) HashCode() int32 {
|
||||
return int32(i)
|
||||
}
|
||||
|
||||
func (i Int32) Compare(t Int32) int {
|
||||
switch {
|
||||
case i > t:
|
||||
return 1
|
||||
case i == t:
|
||||
return 0
|
||||
default:
|
||||
return -1
|
||||
}
|
||||
}
|
44
lang/Int64.go
Normal file
44
lang/Int64.go
Normal file
@ -0,0 +1,44 @@
|
||||
package lang
|
||||
|
||||
import "strconv"
|
||||
|
||||
type Int64 int64
|
||||
|
||||
func (i Int64) AsInt64() int64 {
|
||||
return int64(i)
|
||||
}
|
||||
|
||||
func (i Int64) String() string {
|
||||
return strconv.FormatInt(int64(i), 10)
|
||||
}
|
||||
|
||||
func (i Int64) AsObject() Object {
|
||||
return i
|
||||
}
|
||||
|
||||
func (i Int64) Equals(e Object) bool {
|
||||
i2, ok := e.(Int64)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return i == i2
|
||||
}
|
||||
|
||||
func (i Int64) ToString() String {
|
||||
return NewString(i.String())
|
||||
}
|
||||
|
||||
func (i Int64) HashCode() int32 {
|
||||
return Hash64(&i)
|
||||
}
|
||||
|
||||
func (i Int64) Compare(t Int64) int {
|
||||
switch {
|
||||
case i > t:
|
||||
return 1
|
||||
case i == t:
|
||||
return 0
|
||||
default:
|
||||
return -1
|
||||
}
|
||||
}
|
44
lang/Int8.go
Normal file
44
lang/Int8.go
Normal file
@ -0,0 +1,44 @@
|
||||
package lang
|
||||
|
||||
import "strconv"
|
||||
|
||||
type Int8 int8
|
||||
|
||||
func (i Int8) AsInt8() int8 {
|
||||
return int8(i)
|
||||
}
|
||||
|
||||
func (i Int8) String() string {
|
||||
return strconv.FormatInt(int64(i), 10)
|
||||
}
|
||||
|
||||
func (i Int8) AsObject() Object {
|
||||
return i
|
||||
}
|
||||
|
||||
func (i Int8) Equals(e Object) bool {
|
||||
i2, ok := e.(Int8)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return i == i2
|
||||
}
|
||||
|
||||
func (i Int8) ToString() String {
|
||||
return NewString(i.String())
|
||||
}
|
||||
|
||||
func (i Int8) HashCode() int32 {
|
||||
return int32(i)
|
||||
}
|
||||
|
||||
func (i Int8) Compare(t Int8) int {
|
||||
switch {
|
||||
case i > t:
|
||||
return 1
|
||||
case i == t:
|
||||
return 0
|
||||
default:
|
||||
return -1
|
||||
}
|
||||
}
|
68
lang/Int_test.go
Normal file
68
lang/Int_test.go
Normal file
@ -0,0 +1,68 @@
|
||||
package lang
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestInt_Compare(t *testing.T) {
|
||||
type args struct {
|
||||
t Int
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
i Int
|
||||
args args
|
||||
want int
|
||||
}{
|
||||
{"", 1, args{1}, 0},
|
||||
{"", 1, args{0}, -1},
|
||||
{"", 1, args{2}, 1},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := tt.i.Compare(tt.args.t); got != tt.want {
|
||||
t.Errorf("Compare() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestInt_Equals(t *testing.T) {
|
||||
type args struct {
|
||||
e Object
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
i Int
|
||||
args args
|
||||
want bool
|
||||
}{
|
||||
{"", 1, args{Int(1)}, true},
|
||||
{"", 1, args{Int(0)}, false},
|
||||
{"", 1, args{Int(2)}, false},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := tt.i.Equals(tt.args.e); got != tt.want {
|
||||
t.Errorf("Equals() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestInt_String(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
i Int
|
||||
want string
|
||||
}{
|
||||
{"", 1, "1"},
|
||||
{"", 2, "2"},
|
||||
{"", 3, "3"},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := tt.i.String(); got != tt.want {
|
||||
t.Errorf("String() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
@ -4,3 +4,11 @@ func Nil[T any]() T {
|
||||
var n T
|
||||
return n
|
||||
}
|
||||
|
||||
func Len[T any](array []T) int {
|
||||
return len(array)
|
||||
}
|
||||
|
||||
func Append[T any](slice []T, elems ...T) []T {
|
||||
return append(slice, elems...)
|
||||
}
|
||||
|
@ -1,8 +1,31 @@
|
||||
package lang
|
||||
|
||||
type Object interface {
|
||||
Equals(e Object) bool
|
||||
}
|
||||
import (
|
||||
"fmt"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type (
|
||||
AsObject interface {
|
||||
AsObject() Object
|
||||
}
|
||||
|
||||
Equable interface {
|
||||
Equals(o Object) bool
|
||||
}
|
||||
|
||||
Object interface {
|
||||
AsObject() Object
|
||||
Equals(o Object) bool
|
||||
ToString() String
|
||||
HashCode() int32
|
||||
}
|
||||
|
||||
Any = Object
|
||||
|
||||
BaseObject struct {
|
||||
}
|
||||
)
|
||||
|
||||
func Equals(e Object, t Object) bool {
|
||||
if e == nil {
|
||||
@ -10,3 +33,23 @@ func Equals(e Object, t Object) bool {
|
||||
}
|
||||
return e.Equals(t)
|
||||
}
|
||||
|
||||
func NewBaseObject() BaseObject {
|
||||
return BaseObject{}
|
||||
}
|
||||
|
||||
func (b *BaseObject) AsObject() Object {
|
||||
return b
|
||||
}
|
||||
|
||||
func (b *BaseObject) Equals(o Object) bool {
|
||||
return b == o
|
||||
}
|
||||
|
||||
func (b *BaseObject) ToString() String {
|
||||
return NewString(fmt.Sprint(unsafe.Pointer(b)))
|
||||
}
|
||||
|
||||
func (b *BaseObject) HashCode() int32 {
|
||||
return Hash64(b)
|
||||
}
|
||||
|
53
lang/String.go
Normal file
53
lang/String.go
Normal file
@ -0,0 +1,53 @@
|
||||
package lang
|
||||
|
||||
type String struct {
|
||||
string
|
||||
hashCode int32
|
||||
}
|
||||
|
||||
func NewString(str string) String {
|
||||
return String{string: str}
|
||||
}
|
||||
|
||||
func (i String) AsString() string {
|
||||
return i.string
|
||||
}
|
||||
|
||||
func (i String) String() string {
|
||||
return i.string
|
||||
}
|
||||
|
||||
func (i String) AsObject() Object {
|
||||
return i
|
||||
}
|
||||
|
||||
func (i String) Equals(e Object) bool {
|
||||
i2, ok := e.(String)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return i == i2
|
||||
}
|
||||
|
||||
func (i String) ToString() String {
|
||||
return i
|
||||
}
|
||||
|
||||
func (i String) HashCode() int32 {
|
||||
if i.hashCode != 0 {
|
||||
return i.hashCode
|
||||
}
|
||||
i.hashCode = HashString(i.string)
|
||||
return i.hashCode
|
||||
}
|
||||
|
||||
func (i String) Compare(t String) int {
|
||||
switch {
|
||||
case i.string > t.string:
|
||||
return 1
|
||||
case i == t:
|
||||
return 0
|
||||
default:
|
||||
return -1
|
||||
}
|
||||
}
|
12
lang/String_test.go
Normal file
12
lang/String_test.go
Normal file
@ -0,0 +1,12 @@
|
||||
package lang
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestString_HashCode(t *testing.T) {
|
||||
for i := 1000; i < 1100; i++ {
|
||||
fmt.Println(Int(i).ToString().HashCode())
|
||||
}
|
||||
}
|
63
lang/StrongReference_test.go
Normal file
63
lang/StrongReference_test.go
Normal file
@ -0,0 +1,63 @@
|
||||
package lang
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/tursom/GoCollections/util"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestStrongReference_ToString(t *testing.T) {
|
||||
reference := util.NewStrongReference[Int](1)
|
||||
fmt.Println(reference.ToString())
|
||||
fmt.Println(reference)
|
||||
}
|
||||
|
||||
func TestStrongReference_GetReference(t *testing.T) {
|
||||
type fields struct {
|
||||
reference Int
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
want Int
|
||||
}{
|
||||
{"1", fields{reference: 1}, 1},
|
||||
{"2", fields{reference: 2}, 2},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
r := util.NewStrongReference(tt.fields.reference)
|
||||
if got := r.GetReference(); !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("GetReference() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestStrongReference_SetReference(t *testing.T) {
|
||||
type fields struct {
|
||||
reference Int
|
||||
}
|
||||
type args struct {
|
||||
reference Int
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
args args
|
||||
want Int
|
||||
}{
|
||||
{"1", fields{reference: 1}, args{2}, 2},
|
||||
{"2", fields{reference: 2}, args{3}, 3},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
r := util.NewStrongReference(tt.fields.reference)
|
||||
r.SetReference(tt.args.reference)
|
||||
if got := r.GetReference(); !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("GetReference() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
44
lang/UInt.go
Normal file
44
lang/UInt.go
Normal file
@ -0,0 +1,44 @@
|
||||
package lang
|
||||
|
||||
import "strconv"
|
||||
|
||||
type UInt uint
|
||||
|
||||
func (i UInt) AsUInt() uint {
|
||||
return uint(i)
|
||||
}
|
||||
|
||||
func (i UInt) String() string {
|
||||
return strconv.FormatUint(uint64(i), 10)
|
||||
}
|
||||
|
||||
func (i UInt) AsObject() Object {
|
||||
return i
|
||||
}
|
||||
|
||||
func (i UInt) Equals(e Object) bool {
|
||||
i2, ok := e.(UInt)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return i == i2
|
||||
}
|
||||
|
||||
func (i UInt) ToString() String {
|
||||
return NewString(i.String())
|
||||
}
|
||||
|
||||
func (i UInt) HashCode() int32 {
|
||||
return Int64(i).HashCode()
|
||||
}
|
||||
|
||||
func (i UInt) Compare(t UInt) int {
|
||||
switch {
|
||||
case i > t:
|
||||
return 1
|
||||
case i == t:
|
||||
return 0
|
||||
default:
|
||||
return -1
|
||||
}
|
||||
}
|
44
lang/UInt16.go
Normal file
44
lang/UInt16.go
Normal file
@ -0,0 +1,44 @@
|
||||
package lang
|
||||
|
||||
import "strconv"
|
||||
|
||||
type UInt16 uint16
|
||||
|
||||
func (i UInt16) AsUInt16() uint16 {
|
||||
return uint16(i)
|
||||
}
|
||||
|
||||
func (i UInt16) String() string {
|
||||
return strconv.FormatUint(uint64(i), 10)
|
||||
}
|
||||
|
||||
func (i UInt16) AsObject() Object {
|
||||
return i
|
||||
}
|
||||
|
||||
func (i UInt16) Equals(e Object) bool {
|
||||
i2, ok := e.(UInt16)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return i == i2
|
||||
}
|
||||
|
||||
func (i UInt16) ToString() String {
|
||||
return NewString(i.String())
|
||||
}
|
||||
|
||||
func (i UInt16) HashCode() int32 {
|
||||
return int32(i)
|
||||
}
|
||||
|
||||
func (i UInt16) Compare(t UInt16) int {
|
||||
switch {
|
||||
case i > t:
|
||||
return 1
|
||||
case i == t:
|
||||
return 0
|
||||
default:
|
||||
return -1
|
||||
}
|
||||
}
|
44
lang/UInt32.go
Normal file
44
lang/UInt32.go
Normal file
@ -0,0 +1,44 @@
|
||||
package lang
|
||||
|
||||
import "strconv"
|
||||
|
||||
type UInt32 uint32
|
||||
|
||||
func (i UInt32) AsUInt32() uint32 {
|
||||
return uint32(i)
|
||||
}
|
||||
|
||||
func (i UInt32) String() string {
|
||||
return strconv.FormatUint(uint64(i), 10)
|
||||
}
|
||||
|
||||
func (i UInt32) AsObject() Object {
|
||||
return i
|
||||
}
|
||||
|
||||
func (i UInt32) Equals(e Object) bool {
|
||||
i2, ok := e.(UInt32)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return i == i2
|
||||
}
|
||||
|
||||
func (i UInt32) ToString() String {
|
||||
return NewString(i.String())
|
||||
}
|
||||
|
||||
func (i UInt32) HashCode() int32 {
|
||||
return int32(i)
|
||||
}
|
||||
|
||||
func (i UInt32) Compare(t UInt32) int {
|
||||
switch {
|
||||
case i > t:
|
||||
return 1
|
||||
case i == t:
|
||||
return 0
|
||||
default:
|
||||
return -1
|
||||
}
|
||||
}
|
44
lang/UInt64.go
Normal file
44
lang/UInt64.go
Normal file
@ -0,0 +1,44 @@
|
||||
package lang
|
||||
|
||||
import "strconv"
|
||||
|
||||
type UInt64 uint64
|
||||
|
||||
func (i UInt64) AsUInt64() uint64 {
|
||||
return uint64(i)
|
||||
}
|
||||
|
||||
func (i UInt64) String() string {
|
||||
return strconv.FormatUint(uint64(i), 10)
|
||||
}
|
||||
|
||||
func (i UInt64) AsObject() Object {
|
||||
return i
|
||||
}
|
||||
|
||||
func (i UInt64) Equals(e Object) bool {
|
||||
i2, ok := e.(UInt64)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return i == i2
|
||||
}
|
||||
|
||||
func (i UInt64) ToString() String {
|
||||
return NewString(i.String())
|
||||
}
|
||||
|
||||
func (i UInt64) HashCode() int32 {
|
||||
return Int64(i).HashCode()
|
||||
}
|
||||
|
||||
func (i UInt64) Compare(t UInt64) int {
|
||||
switch {
|
||||
case i > t:
|
||||
return 1
|
||||
case i == t:
|
||||
return 0
|
||||
default:
|
||||
return -1
|
||||
}
|
||||
}
|
46
lang/UInt8.go
Normal file
46
lang/UInt8.go
Normal file
@ -0,0 +1,46 @@
|
||||
package lang
|
||||
|
||||
import "strconv"
|
||||
|
||||
type UInt8 uint8
|
||||
|
||||
type Byte = UInt8
|
||||
|
||||
func (i UInt8) AsUInt8() uint8 {
|
||||
return uint8(i)
|
||||
}
|
||||
|
||||
func (i UInt8) String() string {
|
||||
return strconv.FormatUint(uint64(i), 10)
|
||||
}
|
||||
|
||||
func (i UInt8) AsObject() Object {
|
||||
return i
|
||||
}
|
||||
|
||||
func (i UInt8) Equals(e Object) bool {
|
||||
i2, ok := e.(UInt8)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return i == i2
|
||||
}
|
||||
|
||||
func (i UInt8) ToString() String {
|
||||
return NewString(i.String())
|
||||
}
|
||||
|
||||
func (i UInt8) HashCode() int32 {
|
||||
return int32(i)
|
||||
}
|
||||
|
||||
func (i UInt8) Compare(t UInt8) int {
|
||||
switch {
|
||||
case i > t:
|
||||
return 1
|
||||
case i == t:
|
||||
return 0
|
||||
default:
|
||||
return -1
|
||||
}
|
||||
}
|
27
lang/UInt_test.go
Normal file
27
lang/UInt_test.go
Normal file
@ -0,0 +1,27 @@
|
||||
package lang
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestUInt_HashCode(t *testing.T) {
|
||||
type Tests struct {
|
||||
name string
|
||||
i UInt
|
||||
want int32
|
||||
}
|
||||
var tests []Tests
|
||||
for i := 0; i < 10; i++ {
|
||||
// -i - 1 is ^i
|
||||
// hash code of ^i equals i
|
||||
tests = append(tests, Tests{"test -1", UInt(-i - 1), int32(i)})
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := tt.i.HashCode(); got != tt.want {
|
||||
t.Errorf("HashCode() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
8
main.go
8
main.go
@ -9,11 +9,11 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
_, err := exceptions.Try(func() (interface{}, exceptions.Exception) {
|
||||
_, err := exceptions.Try(func() (any, exceptions.Exception) {
|
||||
panic("test")
|
||||
}, func(r interface{}) (interface{}, exceptions.Exception) {
|
||||
}, func(r any) (any, exceptions.Exception) {
|
||||
fmt.Println("recover from panic", r)
|
||||
return nil, exceptions.NewIndexOutOfBound(fmt.Sprint(r), true)
|
||||
return nil, exceptions.NewIndexOutOfBound(fmt.Sprint(r), nil)
|
||||
})
|
||||
exceptions.Print(err)
|
||||
|
||||
@ -62,7 +62,7 @@ func main() {
|
||||
// fmt.Println(list)
|
||||
//}
|
||||
//
|
||||
//_ = collections.LoopMutable(list, func(element interface{}, iterator collections.MutableIterator) (err exceptions.Exception) {
|
||||
//_ = collections.LoopMutable(list, func(element any, iterator collections.MutableIterator) (err exceptions.Exception) {
|
||||
// if element.(int)&1 == 0 {
|
||||
// err = iterator.Remove()
|
||||
// }
|
||||
|
59
util/Reference.go
Normal file
59
util/Reference.go
Normal file
@ -0,0 +1,59 @@
|
||||
package util
|
||||
|
||||
import "github.com/tursom/GoCollections/lang"
|
||||
|
||||
type (
|
||||
Reference[R any] interface {
|
||||
GetReference() R
|
||||
}
|
||||
MutableReference[R any] interface {
|
||||
SetReference(reference R)
|
||||
GetReference() R
|
||||
}
|
||||
StrongReference[R any] struct {
|
||||
lang.BaseObject
|
||||
reference R
|
||||
}
|
||||
NoReference[R any] struct {
|
||||
lang.BaseObject
|
||||
}
|
||||
)
|
||||
|
||||
func NewStrongReference[R any](reference R) *StrongReference[R] {
|
||||
return &StrongReference[R]{
|
||||
reference: reference,
|
||||
}
|
||||
}
|
||||
|
||||
func NewNoReference[R any]() *NoReference[R] {
|
||||
return &NoReference[R]{}
|
||||
}
|
||||
|
||||
func (r *StrongReference[R]) Equals(o lang.Object) bool {
|
||||
if r == o {
|
||||
return true
|
||||
}
|
||||
if objectReference, ok := o.(Reference[R]); ok {
|
||||
if reference, ok := any(r.reference).(lang.Equable); ok {
|
||||
if referenceObject, ok := any(objectReference.GetReference()).(lang.Object); ok {
|
||||
return reference.Equals(referenceObject)
|
||||
}
|
||||
}
|
||||
}
|
||||
return r == o
|
||||
}
|
||||
|
||||
func (r *StrongReference[R]) SetReference(reference R) {
|
||||
r.reference = reference
|
||||
}
|
||||
|
||||
func (r *StrongReference[R]) GetReference() R {
|
||||
return r.reference
|
||||
}
|
||||
|
||||
func (r *NoReference[R]) SetReference(_ R) {
|
||||
}
|
||||
|
||||
func (r *NoReference[R]) GetReference() R {
|
||||
return lang.Nil[R]()
|
||||
}
|
33
util/Reference_test.go
Normal file
33
util/Reference_test.go
Normal file
@ -0,0 +1,33 @@
|
||||
package util
|
||||
|
||||
import (
|
||||
"github.com/tursom/GoCollections/lang"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestStrongReference_Equals(t *testing.T) {
|
||||
type fields struct {
|
||||
reference int
|
||||
}
|
||||
type args struct {
|
||||
o lang.Object
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
args args
|
||||
want bool
|
||||
}{
|
||||
{"1", fields{1}, args{NewStrongReference[int](1)}, true},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
r := &StrongReference[int]{
|
||||
reference: tt.fields.reference,
|
||||
}
|
||||
if got := r.Equals(tt.args.o); got != tt.want {
|
||||
t.Errorf("Equals() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
1
util/Utils.go
Normal file
1
util/Utils.go
Normal file
@ -0,0 +1 @@
|
||||
package util
|
@ -15,7 +15,7 @@ func (a *arrayList[T]) Iterator() collections.Iterator[T] {
|
||||
}
|
||||
|
||||
func (a *arrayList[T]) Size() int {
|
||||
return len(a.array)
|
||||
return lang.Len(a.array)
|
||||
}
|
||||
|
||||
func (a *arrayList[T]) IsEmpty() bool {
|
||||
@ -44,7 +44,7 @@ type arrayListIterator[T lang.Object] struct {
|
||||
}
|
||||
|
||||
func (a *arrayListIterator[T]) HasNext() bool {
|
||||
return a.index < len(a.array)
|
||||
return a.index < lang.Len(a.array)
|
||||
}
|
||||
|
||||
func (a *arrayListIterator[T]) Next() (r T, err exceptions.Exception) {
|
||||
|
Loading…
Reference in New Issue
Block a user