add basic package type

This commit is contained in:
tursom 2022-03-23 10:15:18 +08:00
parent 47dd188d72
commit ca060c0304
53 changed files with 1545 additions and 87 deletions

View File

@ -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) {

View 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
}

View File

@ -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) {

View File

@ -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()
}

View File

@ -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
View 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
View 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
View 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))
}

View File

@ -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
}

View 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
View 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)
}

View File

@ -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] {

View File

@ -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
View File

@ -0,0 +1,14 @@
package concurrent
type (
Lock interface {
Lock()
Unlock()
}
RWLock interface {
Lock()
Unlock()
RLock()
RUnlock()
}
)

View 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()
}
}

View File

@ -0,0 +1,11 @@
package concurrent
import (
"testing"
)
func TestMutex(t *testing.T) {
mutex := &ReentrantLock{}
mutex.Lock()
mutex.Lock()
}

View File

@ -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(

View File

@ -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
}

View File

@ -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
View 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
}

View File

@ -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(

View File

@ -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(

View File

@ -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(

View File

@ -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:

View File

@ -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
View 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
View 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
View 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
View 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
View 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
View 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"))
}

View File

@ -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
View 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
View 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
View 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
View 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
View 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)
}
})
}
}

View File

@ -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...)
}

View File

@ -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
View 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
View 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())
}
}

View 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
View 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
View 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
View 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
View 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
View 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
View 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)
}
})
}
}

View File

@ -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
View 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
View 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
View File

@ -0,0 +1 @@
package util

View File

@ -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) {