mirror of
https://github.com/tursom/GoCollections.git
synced 2024-12-28 09:30:20 +08:00
create project
This commit is contained in:
commit
f90a7224c2
5
.idea/.gitignore
vendored
Normal file
5
.idea/.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
# 默认忽略的文件
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# 基于编辑器的 HTTP 客户端请求
|
||||
/httpRequests/
|
134
collections/Collection.go
Normal file
134
collections/Collection.go
Normal 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
49
collections/Iterable.go
Normal 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
176
collections/LinkedList.go
Normal 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
|
||||
}
|
88
collections/MutableSubList.go
Normal file
88
collections/MutableSubList.go
Normal 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
42
collections/SubList.go
Normal 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)
|
||||
}
|
26
exceptions/CollectionOperations.go
Normal file
26
exceptions/CollectionOperations.go
Normal 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
10
exceptions/Exception.go
Normal file
@ -0,0 +1,10 @@
|
||||
package exceptions
|
||||
|
||||
import "io"
|
||||
|
||||
type Exception interface {
|
||||
Error() string
|
||||
StackTrace() []StackTrace
|
||||
PrintStackTrace()
|
||||
PrintStackTraceTo(writer io.Writer)
|
||||
}
|
52
exceptions/IndexOutOfBoundError.go
Normal file
52
exceptions/IndexOutOfBoundError.go
Normal 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
60
exceptions/StackTrace.go
Normal 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
27
main.go
Normal 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)
|
||||
//}
|
||||
}
|
Loading…
Reference in New Issue
Block a user