create project

This commit is contained in:
tursom 2021-05-20 17:32:35 +08:00
commit f90a7224c2
11 changed files with 669 additions and 0 deletions

5
.idea/.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
# 默认忽略的文件
/shelf/
/workspace.xml
# 基于编辑器的 HTTP 客户端请求
/httpRequests/

134
collections/Collection.go Normal file
View File

@ -0,0 +1,134 @@
package collections
import (
"collections/exceptions"
"fmt"
"strings"
)
type (
Collection interface {
Iterator() Iterator
Size() uint32
IsEmpty() bool
Contains(element interface{}) bool
ContainsAll(c Collection) bool
}
MutableCollection interface {
Iterator() Iterator
Size() uint32
IsEmpty() bool
Contains(element interface{}) bool
ContainsAll(c Collection) bool
MutableIterator() MutableIterator
Add(element interface{}) bool
Remove(element interface{}) bool
AddAll(c Collection) bool
RemoveAll(c Collection) bool
RetainAll(c Collection) bool
Clear()
}
List interface {
Iterator() Iterator
Size() uint32
IsEmpty() bool
Contains(element interface{}) bool
ContainsAll(c Collection) bool
Get(index uint32) (interface{}, error)
SubList(from, to uint32) List
}
MutableList interface {
Iterator() Iterator
Size() uint32
IsEmpty() bool
Contains(element interface{}) bool
ContainsAll(c Collection) bool
MutableIterator() MutableIterator
Add(element interface{}) bool
Remove(element interface{}) bool
AddAll(c Collection) bool
RemoveAll(c Collection) bool
RetainAll(c Collection) bool
Clear()
Get(index uint32) (interface{}, error)
SubList(from, to uint32) List
Set(index uint32, element interface{}) bool
AddAtIndex(index uint32, element interface{}) bool
RemoveAt(index uint32) bool
SubMutableList(from, to uint32) MutableList
}
)
func Contains(l Collection, element interface{}) bool {
return Loop(l, func(e interface{}) error {
if e == element {
return exceptions.ElementFound
}
return nil
}) != nil
}
func ContainsAll(l Collection, collection Collection) bool {
return Loop(collection, func(e interface{}) error {
if l.Contains(e) {
return nil
} else {
return exceptions.ElementNotFound
}
}) == nil
}
func AddAll(l MutableCollection, collection Collection) bool {
return Loop(collection, func(e interface{}) error {
if !l.Add(e) {
return exceptions.CollectionLoopFinished
}
return nil
}) == nil
}
func RemoveAll(l MutableCollection, collection Collection) bool {
return Loop(collection, func(e interface{}) error {
if !l.Remove(e) {
return exceptions.CollectionLoopFinished
}
return nil
}) == nil
}
func RetainAll(l MutableCollection, collection Collection) bool {
_ = LoopMutable(l, func(element interface{}, iterator MutableIterator) error {
if !collection.Contains(element) {
iterator.Remove()
}
return nil
})
return true
}
func String(l List) string {
if l.IsEmpty() {
return "[]"
}
builder := strings.Builder{}
builder.WriteString("[")
iterator := l.Iterator()
next := iterator.Next()
builder.WriteString(fmt.Sprint(next))
for iterator.HasNext() {
builder.WriteString(", ")
next = iterator.Next()
builder.WriteString(fmt.Sprint(next))
}
builder.WriteString("]")
return builder.String()
}

49
collections/Iterable.go Normal file
View File

@ -0,0 +1,49 @@
package collections
type Iterator interface {
HasNext() bool
Next() interface{}
}
type Iterable interface {
Iterator() Iterator
}
type MutableIterator interface {
HasNext() bool
Next() interface{}
Remove() bool
}
type MutableIterable interface {
Iterator() Iterator
MutableIterator() MutableIterator
}
func Loop(iterable Iterable, f func(element interface{}) error) error {
if f == nil {
return nil
}
iterator := iterable.Iterator()
for iterator.HasNext() {
err := f(iterator.Next())
if err != nil {
return err
}
}
return nil
}
func LoopMutable(iterable MutableIterable, f func(element interface{}, iterator MutableIterator) error) error {
if f == nil {
return nil
}
iterator := iterable.MutableIterator()
for iterator.HasNext() {
err := f(iterator.Next(), iterator)
if err != nil {
return err
}
}
return nil
}

176
collections/LinkedList.go Normal file
View File

@ -0,0 +1,176 @@
package collections
import (
"collections/exceptions"
)
type (
LinkedList struct {
head *linkedListNode
size uint32
}
linkedListNode struct {
prev, next *linkedListNode
value interface{}
}
)
func (l LinkedList) String() string {
return String(l)
}
func NewLinkedList() *LinkedList {
tail := &linkedListNode{}
tail.prev = tail
tail.next = tail
return &LinkedList{tail, 0}
}
func (l LinkedList) Size() uint32 {
return l.size
}
func (l LinkedList) IsEmpty() bool {
return l.size == 0
}
func (l LinkedList) Contains(element interface{}) bool {
return Contains(&l, element)
}
func (l LinkedList) ContainsAll(c Collection) bool {
return ContainsAll(&l, c)
}
func (l *LinkedList) Add(element interface{}) bool {
l.size++
node := &linkedListNode{l.head.prev, l.head, element}
node.next.prev = node
node.prev.next = node
return true
}
func (l *LinkedList) Remove(element interface{}) bool {
return LoopMutable(l, func(e interface{}, iterator MutableIterator) error {
if element == e {
iterator.Remove()
return exceptions.CollectionLoopFinished
}
return nil
}) != nil
}
func (l *LinkedList) AddAll(c Collection) bool {
return AddAll(l, c)
}
func (l *LinkedList) RemoveAll(c Collection) bool {
return RemoveAll(l, c)
}
func (l *LinkedList) RetainAll(c Collection) bool {
return RetainAll(l, c)
}
func (l *LinkedList) Clear() {
l.head.next = l.head
l.size = 0
}
func (l LinkedList) SubList(from, to uint32) List {
return NewSubList(l, from, to)
}
func (l *LinkedList) Set(index uint32, element interface{}) bool {
node := l.head
for node != l.head {
if index == 0 {
node.value = element
return true
}
index--
}
return false
}
func (l *LinkedList) AddAtIndex(index uint32, element interface{}) bool {
node := l.head
for node != l.head {
if index == 0 {
l.size++
node.next = &linkedListNode{node, node.next, element}
node.next.next.prev = node.next
return true
}
index--
}
return false
}
func (l *LinkedList) RemoveAt(index uint32) bool {
node := l.head
for node != l.head {
if index == 0 {
l.size--
node.remove()
return true
}
index--
}
return false
}
func (l *LinkedList) SubMutableList(from, to uint32) MutableList {
return NewMutableSubList(l, from, to)
}
func (l LinkedList) Get(index uint32) (interface{}, error) {
node := l.head
for node != l.head {
if index == 0 {
return node.value, nil
}
index--
}
return nil, exceptions.NewIndexOutOfBound("", true)
}
func (l LinkedList) Iterator() Iterator {
return l.MutableIterator()
}
func (l *LinkedList) MutableIterator() MutableIterator {
return &linkedListIterator{l, l.head.next, l.head}
}
type linkedListIterator struct {
list *LinkedList
node, head *linkedListNode
}
func (l *linkedListIterator) HasNext() bool {
return l.node != l.head
}
func (l *linkedListIterator) Next() interface{} {
if l.node == l.head {
panic("iterator loop finished")
}
l.node = l.node.next
return l.node.prev.value
}
func (l *linkedListIterator) Remove() bool {
if l.node.prev == l.head {
return false
}
l.node.prev.remove()
l.list.size--
return true
}
func (l *linkedListNode) remove() {
l.next.prev = l.prev
l.prev.next = l.next
}

View File

@ -0,0 +1,88 @@
package collections
type MutableSubList struct {
list MutableList
from, to uint32
}
func NewMutableSubList(list MutableList, from, to uint32) *MutableSubList {
return &MutableSubList{list, from, to}
}
func (s *MutableSubList) Iterator() Iterator {
iterator := s.list.Iterator()
for i := 0; i < int(s.from); i++ {
iterator.Next()
}
return iterator
}
func (s *MutableSubList) Size() uint32 {
return s.to - s.from
}
func (s *MutableSubList) IsEmpty() bool {
return s.Size() == 0
}
func (s *MutableSubList) Contains(element interface{}) bool {
return Contains(s, element)
}
func (s *MutableSubList) ContainsAll(c Collection) bool {
return ContainsAll(s, c)
}
func (s *MutableSubList) Get(index uint32) (interface{}, error) {
return s.list.Get(index + s.from)
}
func (s *MutableSubList) SubList(from, to uint32) List {
return NewSubList(s, from, to)
}
func (s *MutableSubList) MutableIterator() MutableIterator {
return nil
}
func (s *MutableSubList) Add(element interface{}) bool {
return false
}
func (s *MutableSubList) Remove(element interface{}) bool {
return false
}
func (s *MutableSubList) AddAll(c Collection) bool {
return false
}
func (s *MutableSubList) RemoveAll(c Collection) bool {
return false
}
func (s *MutableSubList) RetainAll(c Collection) bool {
return false
}
func (s *MutableSubList) Clear() {
}
func (s *MutableSubList) Set(index uint32, element interface{}) bool {
if index >= s.to-s.from {
return false
}
return s.list.Set(index+s.from, element)
}
func (s *MutableSubList) AddAtIndex(index uint32, element interface{}) bool {
return false
}
func (s *MutableSubList) RemoveAt(index uint32) bool {
return false
}
func (s *MutableSubList) SubMutableList(from, to uint32) MutableList {
return NewMutableSubList(s.list, s.from+from, to)
}

42
collections/SubList.go Normal file
View File

@ -0,0 +1,42 @@
package collections
type SubList struct {
list List
from, to uint32
}
func NewSubList(list List, from, to uint32) *SubList {
return &SubList{list, from, to}
}
func (s *SubList) Iterator() Iterator {
iterator := s.list.Iterator()
for i := 0; i < int(s.from); i++ {
iterator.Next()
}
return iterator
}
func (s *SubList) Size() uint32 {
return s.to - s.from
}
func (s *SubList) IsEmpty() bool {
return s.Size() == 0
}
func (s *SubList) Contains(element interface{}) bool {
return Contains(s, element)
}
func (s *SubList) ContainsAll(c Collection) bool {
return ContainsAll(s, c)
}
func (s *SubList) Get(index uint32) (interface{}, error) {
return s.list.Get(index + s.from)
}
func (s *SubList) SubList(from, to uint32) List {
return NewSubList(s, from, to)
}

View File

@ -0,0 +1,26 @@
package exceptions
var ElementFound = ElementFoundThrowable{}
var ElementNotFound = ElementFoundThrowable{}
var CollectionLoopFinished = CollectionLoop{}
type ElementFoundThrowable struct {
}
func (e ElementFoundThrowable) Error() string {
return "element found"
}
type ElementNotFoundThrowable struct {
}
func (e ElementNotFoundThrowable) Error() string {
return "element not found"
}
type CollectionLoop struct {
}
func (e CollectionLoop) Error() string {
return "collection loop finished"
}

10
exceptions/Exception.go Normal file
View File

@ -0,0 +1,10 @@
package exceptions
import "io"
type Exception interface {
Error() string
StackTrace() []StackTrace
PrintStackTrace()
PrintStackTraceTo(writer io.Writer)
}

View File

@ -0,0 +1,52 @@
package exceptions
import (
"fmt"
"io"
"os"
)
type IndexOutOfBound struct {
message string
stackTrace []StackTrace
}
func NewIndexOutOfBound(message string, getStackTrace bool) IndexOutOfBound {
var stackTrace []StackTrace = nil
if getStackTrace {
stackTrace = GetStackTrace()
}
return IndexOutOfBound{
message: message,
stackTrace: stackTrace,
}
}
func (i IndexOutOfBound) StackTrace() []StackTrace {
return i.stackTrace
}
func (i IndexOutOfBound) PrintStackTrace() {
i.PrintStackTraceTo(os.Stderr)
}
func (i IndexOutOfBound) PrintStackTraceTo(writer io.Writer) {
_, err := fmt.Fprintln(writer, "exception caused IndexOutOfBound:", i.Error())
if err != nil {
return
}
if i.stackTrace == nil {
return
}
for _, stackTrace := range i.stackTrace {
stackTrace.PrintLn(writer)
}
}
func (i IndexOutOfBound) Error() string {
if len(i.message) == 0 {
return "index out of bound"
} else {
return i.message
}
}

60
exceptions/StackTrace.go Normal file
View File

@ -0,0 +1,60 @@
package exceptions
import (
"fmt"
"io"
"runtime"
)
type StackTrace struct {
pc uintptr
file string
line int
}
func (s StackTrace) Pc() uintptr {
return s.pc
}
func (s StackTrace) File() string {
return s.file
}
func (s StackTrace) Line() int {
return s.line
}
func (s StackTrace) Print(writer io.Writer) {
_, err := fmt.Fprint(writer, "at", s.file, s.line)
if err != nil {
return
}
}
func (s StackTrace) PrintLn(writer io.Writer) {
_, err := fmt.Fprintf(writer, "\tat %s(%d)\n", s.file, s.line)
if err != nil {
return
}
}
func GetStackTrace() []StackTrace {
stackTraceMax := 16
stackTraceUsed := 0
stackTrace := make([]StackTrace, stackTraceMax)
for i := 1; ; i++ {
pc, file, line, ok := runtime.Caller(i)
if !ok {
break
}
if stackTraceUsed == stackTraceMax {
stackTraceMax *= 2
stackTraceOld := stackTrace
stackTrace = make([]StackTrace, stackTraceMax)
copy(stackTrace, stackTraceOld)
}
stackTrace[stackTraceUsed] = StackTrace{pc, file, line}
stackTraceUsed++
}
return stackTrace[0:stackTraceUsed]
}

27
main.go Normal file
View File

@ -0,0 +1,27 @@
package main
import (
"collections/collections"
"fmt"
)
func main() {
list := collections.NewLinkedList()
fmt.Println(list)
for i := 0; i < 20; i++ {
list.Add(i)
//fmt.Println(list)
}
_ = collections.LoopMutable(list, func(element interface{}, iterator collections.MutableIterator) error {
if element.(int)&1 == 0 {
iterator.Remove()
}
fmt.Println(list)
return nil
})
//for i := 0; i < 10; i++ {
// list.Remove(i * 2)
// fmt.Println(list)
//}
}