diff --git a/datastructure/hashmap/hashmap_test.go b/datastructure/hashmap/hashmap_test.go index 9a1c29b..747af19 100644 --- a/datastructure/hashmap/hashmap_test.go +++ b/datastructure/hashmap/hashmap_test.go @@ -74,3 +74,34 @@ func TestHashMap_KeysValues(t *testing.T) { assert.Equal(3, len(values)) assert.Equal(3, len(keys)) } + +func TestHashMap_Keys(t *testing.T) { + t.Parallel() + + assert := internal.NewAssert(t, "TestHashMap_Keys") + + hm := NewHashMap() + + hm.Put("a", 1) + hm.Put("b", 2) + hm.Put("c", 3) + + keys := hm.Keys() + + assert.Equal(3, len(keys)) +} + +func TestHashMap_GetOrDefault(t *testing.T) { + t.Parallel() + + assert := internal.NewAssert(t, "TestHashMap_GetOrDefault") + + hm := NewHashMap() + + hm.Put("a", 1) + hm.Put("b", 2) + hm.Put("c", 3) + + assert.Equal(1, hm.GetOrDefault("a", 5)) + assert.Equal(5, hm.GetOrDefault("d", 5)) +} diff --git a/datastructure/list/copyonwritelist.go b/datastructure/list/copyonwritelist.go new file mode 100644 index 0000000..0fbd382 --- /dev/null +++ b/datastructure/list/copyonwritelist.go @@ -0,0 +1,290 @@ +package datastructure + +import ( + "reflect" + "sync" +) + +type CopyOnWriteList[T any] struct { + data []T + lock sync.Locker +} + +// NewCopyOnWriteList Creates an empty list. +func NewCopyOnWriteList[T any](data []T) *CopyOnWriteList[T] { + return &CopyOnWriteList[T]{data: data, lock: &sync.RWMutex{}} +} + +func (c *CopyOnWriteList[T]) getList() []T { + return c.data +} +func (c *CopyOnWriteList[T]) setList(data []T) { + c.data = data +} + +// Size returns the number of elements in this list. +func (c *CopyOnWriteList[T]) Size() int { + return len(c.getList()) +} + +// IsEmpty returns true if this list contains no elements. +func (c *CopyOnWriteList[T]) IsEmpty() bool { + return c.Size() == 0 +} + +// Contain returns true if this list contains the specified element. +func (c *CopyOnWriteList[T]) Contain(e T) bool { + list := c.getList() + return indexOf(e, list, 0, c.Size()) >= 0 +} + +// ValueOf returns the index of the first occurrence of the specified element in this list, or null if this list does not contain the element. +func (c *CopyOnWriteList[T]) ValueOf(index int) *T { + list := c.getList() + if index < 0 || index >= len(c.data) { + return nil + } + return get(list, index) +} + +// IndexOf returns the index of the first occurrence of the specified element in this list, or -1 if this list does not contain the element. +func (c *CopyOnWriteList[T]) IndexOf(e T) int { + list := c.getList() + return indexOf(e, list, 0, c.Size()) +} + +// indexOf returns the index of the first occurrence of the specified element in this list, or -1 if this list does not contain the element. +// start the start position of the search (inclusive) +// end the end position of the search (exclusive) +func indexOf[T any](o T, e []T, start int, end int) int { + if start >= end { + return -1 + } + for i := start; i < end; i++ { + if reflect.DeepEqual(e[i], o) { + return i + } + } + return -1 +} + +// LastIndexOf returns the index of the last occurrence of the specified element in this list, or -1 if this list does not contain the element. +func (c *CopyOnWriteList[T]) LastIndexOf(e T) int { + list := c.getList() + return lastIndexOf(e, list, 0, c.Size()) +} + +// lastIndexOf returns the index of the last occurrence of the specified element in this list, or -1 if this list does not contain the element. +// start the start position of the search (inclusive) +// end the end position of the search (exclusive) +func lastIndexOf[T any](o T, e []T, start int, end int) int { + if start >= end { + return -1 + } + for i := end - 1; i >= start; i-- { + if reflect.DeepEqual(e[i], o) { + return i + } + } + return -1 +} + +// get returns the element at the specified position in this list. +func get[T any](o []T, index int) *T { + return &o[index] +} + +// Get returns the element at the specified position in this list. +func (c *CopyOnWriteList[T]) Get(index int) *T { + list := c.getList() + if index < 0 || index >= len(list) { + return nil + } + return get(list, index) +} + +func (c *CopyOnWriteList[T]) set(index int, e T) (oldValue *T) { + lock := c.lock + lock.Lock() + defer lock.Unlock() + + list := c.getList() + oldValue = get(list, index) + + if reflect.DeepEqual(oldValue, e) { + c.setList(list) + } else { + newList := make([]T, len(list)) + copy(newList, list) + newList[index] = e + c.setList(newList) + } + return +} + +// Set replaces the element at the specified position in this list with the specified element. +func (c *CopyOnWriteList[T]) Set(index int, e T) (oldValue *T, ok bool) { + list := c.getList() + if index < 0 || index >= len(list) { + return oldValue, false + } + return c.set(index, e), true +} + +// Add appends the specified element to the end of this list. +func (c *CopyOnWriteList[T]) Add(e T) bool { + lock := c.lock + lock.Lock() + defer lock.Unlock() + + list := c.getList() + newList := make([]T, len(list)+1) + copy(newList, list) + newList[len(list)] = e + c.setList(newList) + return true +} + +// AddAll appends all the elements in the specified collection to the end of this list +func (c *CopyOnWriteList[T]) AddAll(e []T) bool { + lock := c.lock + lock.Lock() + defer lock.Unlock() + + list := c.getList() + newList := make([]T, len(list)+len(e)) + copy(newList, list) + copy(newList[len(list):], e) + c.setList(newList) + return true +} + +// AddByIndex inserts the specified element at the specified position in this list. +func (c *CopyOnWriteList[T]) AddByIndex(index int, e T) bool { + lock := c.lock + lock.Lock() + defer lock.Unlock() + + list := c.getList() + length := len(list) + if index < 0 || index > length { + return false + } + var newList []T + var numMove = length - index + if numMove == 0 { + newList = make([]T, length+1) + copy(newList, list) + } else { + newList = make([]T, length+1) + copy(newList, list[:index]) + copy(newList[index+1:], list[index:]) + } + newList[index] = e + c.setList(newList) + return true +} + +// delete removes the element at the specified position in this list. +func (c *CopyOnWriteList[T]) delete(index int) *T { + lock := c.lock + lock.Lock() + defer lock.Unlock() + + list := c.getList() + length := len(list) + + oldValue := get(list, index) + numMove := length - index - 1 + var newList []T + if numMove == 0 { + newList = make([]T, length-1) + copy(newList, list[:index]) + } else { + newList = make([]T, length-1) + copy(newList, list[:index]) + copy(newList[index:], list[index+1:]) + } + + c.setList(newList) + return oldValue +} + +// DeleteAt removes the element at the specified position in this list. +func (c *CopyOnWriteList[T]) DeleteAt(index int) (*T, bool) { + list := c.getList() + if index < 0 || index >= len(list) { + return nil, false + } + return c.delete(index), true +} + +// DeleteBy removes the first occurrence of the specified element from this list, if it is present. +func (c *CopyOnWriteList[T]) DeleteBy(o T) (*T, bool) { + list := c.getList() + index := indexOf(o, list, 0, len(list)) + if index == -1 { + return nil, false + } + return c.delete(index), true +} + +// DeleteRange removes from this list all the elements whose index is between fromIndex, inclusive, and toIndex, exclusive. +// left close and right open +func (c *CopyOnWriteList[T]) DeleteRange(start int, end int) { + lock := c.lock + lock.Lock() + defer lock.Unlock() + + list := c.getList() + length := len(list) + if start < 0 || end > length || start > end { + return + } + var newList []T + numMove := length - end + if numMove == 0 { + newList = make([]T, length-(end-start)) + copy(newList, list[:start]) + } else { + newList = make([]T, length-(end-start)) + copy(newList, list[:start]) + copy(newList[start:], list[end:]) + } + c.setList(newList) +} + +// DeleteIf removes all the elements of this collection that satisfy the given predicate. +func (c *CopyOnWriteList[T]) DeleteIf(f func(T) bool) { + lock := c.lock + lock.Lock() + defer lock.Unlock() + + list := c.getList() + length := len(list) + var newList []T + for i := 0; i < length; i++ { + if !f(list[i]) { + newList = append(newList, list[i]) + } + } + c.setList(newList) +} + +// Equal returns true if the specified object is equal to this list. +func (c *CopyOnWriteList[T]) Equal(other *[]T) bool { + if other == nil { + return false + } + if c.Size() != len(*other) { + return false + } + list := c.getList() + otherList := NewCopyOnWriteList(*other).getList() + for i := 0; i < len(list); i++ { + if !reflect.DeepEqual(list[i], otherList[i]) { + return false + } + } + return true +} diff --git a/datastructure/list/copyonwritelist_test.go b/datastructure/list/copyonwritelist_test.go new file mode 100644 index 0000000..54c1609 --- /dev/null +++ b/datastructure/list/copyonwritelist_test.go @@ -0,0 +1,132 @@ +package datastructure + +import ( + "github.com/duke-git/lancet/v2/internal" + "testing" +) + +func TestCopyOnWriteList_ValueOf(t *testing.T) { + list := NewCopyOnWriteList([]int{1, 2, 3, 4, 5}) + + assert := internal.NewAssert(t, "CopyOnWriteList_IndexOf") + of := list.ValueOf(3) + assert.Equal(4, *of) +} + +func TestCopyOnWriteList_Contains(t *testing.T) { + list := NewCopyOnWriteList([]int{1, 2, 3, 4, 5}) + assert := internal.NewAssert(t, "CopyOnWriteList_Contains") + assert.Equal(true, list.Contain(3)) +} + +func TestCopyOnWriteList_IsEmpty(t *testing.T) { + list := NewCopyOnWriteList([]int{}) + assert := internal.NewAssert(t, "CopyOnWriteList_IsEmpty") + assert.Equal(true, list.IsEmpty()) +} + +func TestCopyOnWriteList_size(t *testing.T) { + list := NewCopyOnWriteList([]int{1, 2, 3, 4, 5}) + assert := internal.NewAssert(t, "CopyOnWriteList_size") + assert.Equal(5, list.Size()) +} + +func TestCopyOnWriteList_GetList(t *testing.T) { + list := NewCopyOnWriteList([]int{1, 2, 3, 4, 5}) + assert := internal.NewAssert(t, "CopyOnWriteList_GetList") + assert.Equal([]int{1, 2, 3, 4, 5}, list.getList()) +} + +func TestCopyOnWriteList_Get(t *testing.T) { + list := NewCopyOnWriteList([]int{1, 2, 3, 4, 5}) + assert := internal.NewAssert(t, "CopyOnWriteList_Get") + i := list.Get(2) + assert.Equal(3, *i) +} + +func TestCopyOnWriteList_Set(t *testing.T) { + list := NewCopyOnWriteList([]int{1, 2, 3, 4, 5}) + assert := internal.NewAssert(t, "CopyOnWriteList_Set") + list.Set(2, 6) + assert.Equal(6, list.getList()[2]) +} + +func TestCopyOnWriteList_Add(t *testing.T) { + list := NewCopyOnWriteList([]int{1, 2, 3, 4, 5}) + assert := internal.NewAssert(t, "CopyOnWriteList_Add") + list.Add(6) + assert.Equal([]int{1, 2, 3, 4, 5, 6}, list.getList()) +} + +func TestCopyOnWriteList_AddAll(t *testing.T) { + list := NewCopyOnWriteList([]int{1, 2, 3, 4, 5}) + assert := internal.NewAssert(t, "CopyOnWriteList_AddAll") + list.AddAll([]int{6, 7, 8}) + assert.Equal([]int{1, 2, 3, 4, 5, 6, 7, 8}, list.getList()) +} + +func TestCopyOnWriteList_AddByIndex(t *testing.T) { + list := NewCopyOnWriteList([]int{1, 2, 3, 4, 5}) + assert := internal.NewAssert(t, "CopyOnWriteList_AddByIndex") + list.AddByIndex(2, 6) + assert.Equal([]int{1, 2, 6, 3, 4, 5}, list.getList()) +} + +func TestCopyOnWriteList_DeleteAt2(t *testing.T) { + list := NewCopyOnWriteList([]int{1, 2, 3, 4, 5}) + assert := internal.NewAssert(t, "CopyOnWriteList_RemoveByIndex") + list.DeleteAt(2) + assert.Equal([]int{1, 2, 4, 5}, list.getList()) +} + +func TestCopyOnWriteList_RemoveByValue(t *testing.T) { + list := NewCopyOnWriteList([]int{1, 2, 3, 4, 5}) + assert := internal.NewAssert(t, "CopyOnWriteList_RemoveByValue") + list.DeleteBy(3) + assert.Equal([]int{1, 2, 4, 5}, list.getList()) +} + +func TestCopyOnWriteList_RemoveRange(t *testing.T) { + list := NewCopyOnWriteList([]int{1, 2, 3, 4, 5}) + assert := internal.NewAssert(t, "CopyOnWriteList_RemoveRange") + list.DeleteRange(1, 3) + assert.Equal([]int{1, 4, 5}, list.getList()) +} + +func TestCopyOnWriteList_LastIndexOf(t *testing.T) { + list := NewCopyOnWriteList([]int{1, 2, 3, 4, 5, 3}) + assert := internal.NewAssert(t, "CopyOnWriteList_LastIndexOf") + assert.Equal(5, list.LastIndexOf(3)) +} + +func TestCopyOnWriteList_DeleteAt(t *testing.T) { + list := NewCopyOnWriteList([]int{1, 2, 3, 4, 5, 3}) + assert := internal.NewAssert(t, "CopyOnWriteList_DeleteAt") + list.DeleteAt(2) + assert.Equal([]int{1, 2, 4, 5, 3}, list.getList()) +} + +func TestCopyOnWriteList_DeleteBy(t *testing.T) { + list := NewCopyOnWriteList([]int{1, 2, 3, 4, 5, 3}) + assert := internal.NewAssert(t, "CopyOnWriteList_DeleteBy") + list.DeleteBy(3) + assert.Equal([]int{1, 2, 4, 5, 3}, list.getList()) +} + +func TestCopyOnWriteList_DeleteIf(t *testing.T) { + list := NewCopyOnWriteList([]int{1, 2, 3, 4, 5, 3, 6}) + assert := internal.NewAssert(t, "CopyOnWriteList_DeleteIf") + + list.DeleteIf(func(i int) bool { + return i%2 == 0 + }) + + assert.Equal([]int{1, 3, 5, 3}, list.getList()) +} + +func TestCopyOnWriteList_Equal(t *testing.T) { + list := NewCopyOnWriteList([]int{1, 2, 3, 4, 5, 3, 6}) + assert := internal.NewAssert(t, "CopyOnWriteList_Equal") + + assert.Equal(true, list.Equal(&[]int{1, 2, 3, 4, 5, 3, 6})) +} diff --git a/datastructure/list/list.go b/datastructure/list/list.go index 2a359e4..78813f7 100644 --- a/datastructure/list/list.go +++ b/datastructure/list/list.go @@ -271,7 +271,7 @@ func (l *List[T]) Reverse() { } } -// Unique remove duplicate items in list. +// Unique delete duplicate items in list. func (l *List[T]) Unique() { data := l.data size := len(data) @@ -294,7 +294,7 @@ func (l *List[T]) Unique() { l.data = uniqueData } -// Union creates a new list contain all element in list l and other, remove duplicate element. +// Union creates a new list contain all element in list l and other, delete duplicate element. func (l *List[T]) Union(other *List[T]) *List[T] { result := NewList([]T{}) diff --git a/docs/datastructure/copyonwritelist.md b/docs/datastructure/copyonwritelist.md new file mode 100644 index 0000000..1b21b39 --- /dev/null +++ b/docs/datastructure/copyonwritelist.md @@ -0,0 +1,415 @@ +# CopyOnWriteList +CopyOnWriteList is a thread-safe list implementation that uses go slicing as its base. +. When writing, a new slice is copied and assigned to the original slice when writing is complete.When reading, the original slice is read directly. + +## 源码 +- [https://github.com/duke-git/lancet/blob/main/datastructure/list/copyonwritelist.go](https://github.com/duke-git/lancet/blob/main /datastructure/list/copyonwritelist.go) + +## 用法 +```go +import ( +"github.com/duke-git/lancet/datastructure/list" +) + +``` + +
+ +## 目录 +- [NewCopyOnWriteList](#NewCopyOnWriteList) +- [Size](#Size) +- [Get](#Get) +- [Set](#Set) +- [Remove](#Remove) +- [IndexOf](#IndexOf) +- [LastIndexOf](#LastIndexOf) +- [IsEmpty](#IsEmpty) +- [Contain](#Contain) +- [ValueOf](#ValueOf) +- [Add](#Add) +- [AddAll](#AddAll) +- [AddByIndex](#AddByIndex) +- [DeleteAt](#DeleteAt) +- [DeleteIf](#DeleteIf) +- [DeleteBy](#DeleteBy) +- [DeleteRange](#DeleteRange) +- [Equal](#Equal) + + +## Documentation + +### NewCopyOnWriteList +Returns a CopyOnWriteList with empty slices. +```go +type CopyOnWriteList[T any] struct { + data []T + lock sync. +} + +func NewCopyOnWriteList() *CopyOnWriteList + +``` +#### Example +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/datastructure/list" +) + +func main() { + l := list.NewCopyOnWriteList([]int{1,2,3}) + fmt.Println(l) +} + +fmt.Println(l) } +### Size +Returns the length of the CopyOnWriteList. +```go +func (l *CopyOnWriteList[T]) Size() int +``` +#### Example +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/datastructure/list" +) + +func main() { + l := list.NewCopyOnWriteList([]int{1,2,3}) + fmt.Println(l.Size()) +} + +``` + +### Get +Returns the element at the specified position in the list +```go +func (c *CopyOnWriteList[T]) Get(index int) *T +``` + +#### Example +```go +package main + +import ( +"fmt" +"github.com/duke-git/lancet/datastructure/list" +) + +func main() { +l := list.NewCopyOnWriteList([]int{1,2,3}) +fmt.Println(l.Get(2)) +} + +``` + + +### Set +Replaces the element at the specified position in this list with the specified element. +```go +func (c *CopyOnWriteList[T]) Set(index int, e T) (oldValue *T, ok bool) +``` + +#### Example +```go +package main + +import ( +"fmt" +"github.com/duke-git/lancet/datastructure/list" +) + +func main() { +l := list.NewCopyOnWriteList([]int{1,2,3}) +fmt.Println(l.Set(2, 4)) +} + +``` +### Remove + +### IndexOf +Returns the index of the value in the list, or -1 if not found. +```go +func (c *CopyOnWriteList[T]) IndexOf(e T) int +``` +#### Example +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/datastructure/list" +) + +func main() { + l := list.NewCopyOnWriteList([]int{1,2,3}) + fmt.Println(l.IndexOf(1)) +} + +``` + +### LastIndexOf +Returns the index of the last occurrence of the specified element in this list, or -1 if this list does not contain that element. + +```go +func (c *CopyOnWriteList[T]) LastIndexOf(e T) int +``` + +#### Example +```go +package main + +import ( +"fmt" +"github.com/duke-git/lancet/datastructure/list" +) + +func main() { +l := list.NewCopyOnWriteList([]int{1,2,3,1}) +fmt.Println(l.LastIndexOf(1)) +} + +``` + +### IsEmpty +Returns true if this list does not contain any elements. +```go +func (c *CopyOnWriteList[T]) IsEmpty() bool +``` + +#### Example +```go +package main + +import ( +"fmt" +"github.com/duke-git/lancet/datastructure/list" +) + +func main() { +l := list.NewCopyOnWriteList([]int{}) +fmt.Println(l.IsEmpty()) +} +``` + + + +### Contain +Determines if a CopyOnWriteList contains an element. +```go +func (c *CopyOnWriteList[T]) Contain(e T) bool +``` +#### Example +```go +package main + +import ( +"fmt" +"github.com/duke-git/lancet/datastructure/list" +) + +func main() { +l := list.NewCopyOnWriteList([]int{1,2,3}) +fmt.Println(l.Contain(1)) +} +``` + + +### ValueOf +Returns a pointer to the value at the index in the list +```go +func (c *CopyOnWriteList[T]) ValueOf(index int) []T +``` + +#### Example +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/datastructure/list" +) + +func main() { + l := list.NewCopyOnWriteList([]int{1,2,3}) + fmt.Println(l.ValueOf(2)) +} + +``` + +### Add +Appends the specified element to the end of the list. +```go +func (c *CopyOnWriteList[T]) Add(e T) bool +``` + +#### Example +```go + +package main + +import ( + "fmt" + "github.com/duke-git/lancet/datastructure/list" +) + +func main() { + l := list.NewCopyOnWriteList([]int{1,2,3}) + l.Add(4) + fmt.Println(l.getList()) +} + +``` + +### AddAll +Appends all the elements of the specified collection to the end of this list +```go +func (c *CopyOnWriteList[T]) AddAll(e []T) bool +``` + +#### Example +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/datastructure/list" +) + +func main() { + l := list.NewCopyOnWriteList([]int{1,2,3}) + l.AddAll([]int{4,5,6}) + fmt.Println(l.getList()) +} + +``` + +### AddByIndex +Inserts the specified element into the list at the specified position. + +```go +func (c *CopyOnWriteList[T]) AddByIndex(index int, e T) bool +``` +#### Example +```go +package main +import ( +"fmt" +"github.com/duke-git/lancet/datastructure/list" +) +func main() { +l := list.NewCopyOnWriteList([]int{1,2,3}) +list.AddByIndex(2, 6) +fmt.Println(l.getList()) +} + +``` + +### DeleteAt +Removes the element at the specified position in this list. +```go +func (c *CopyOnWriteList[T]) DeleteAt(index int) (oldValue *T, ok bool) +``` +#### Example +```go +package main +import ( +"fmt" +"github.com/duke-git/lancet/datastructure/list" +) + +func main() { +l := list.NewCopyOnWriteList([]int{1,2,3}) +list.DeleteAt(2) +fmt.Println(l.getList()) +} +``` + +### DeleteIf +Removes the first occurrence of the specified element from this list (if it exists). +```go +func (c *CopyOnWriteList[T]) DeleteIf(func(T) bool) (oldValue *T, ok bool) +``` +#### Example +```go +package main +import ( + "fmt" + "github.com/duke-git/lancet/datastructure/list" +) + +func main() { + l := list.NewCopyOnWriteList([]int{1,2,3}) + list.DeleteIf(func(i int) bool { + return i == 2 + }) + fmt.Println(l.getList()) +} +``` + +### DeleteBy +Deletes the first occurrence of the specified element from this list (if it exists). +```## go +func (c *CopyOnWriteList[T]) DeleteBy(e T) (*T bool) +``` +#### Example +```go +package main +import ( + "fmt" + "github.com/duke-git/lancet/datastructure/list" +) + +func main() { + l := list.NewCopyOnWriteList([]int{1,2,3}) + list.DeleteBy(2) + fmt.Println(l.getList()) +} +``` + + +### DeleteRange +Deletes all elements from this list with indexes between fromIndex (included) and toIndex (not included). +(leftCloseRightOpen) +```go +func (c *CopyOnWriteList[T]) DeleteRange(start int, end int) +``` + +#### Example +```go +package main +import ( +"fmt" +"github.com/duke-git/lancet/datastructure/list" +) + +func main() { +l := list.NewCopyOnWriteList([]int{1,2,3,4,5,6,7,8,9}) +list.DeleteRange(2, 5) +fmt.Println(l.getList()) +} +``` + +### Equal +Returns true if the specified object is equal to this list + +```go +func (c *CopyOnWriteList[T]) Equal(e []T) bool +``` +#### Example +```go +package main +import ( + "fmt" + "github.com/duke-git/lancet/datastructure/list" +) + +func main() { + l := list.NewCopyOnWriteList([]int{1,2,3,4,5,6,7,8,9}) + fmt.Println(l.Equal([]int{1,2,3,4,5,6,7,8,9})) +} +``` \ No newline at end of file diff --git a/docs/datastructure/copyonwritelist_zh-CN.md b/docs/datastructure/copyonwritelist_zh-CN.md new file mode 100644 index 0000000..db6fa74 --- /dev/null +++ b/docs/datastructure/copyonwritelist_zh-CN.md @@ -0,0 +1,415 @@ +# CopyOnWriteList +CopyOnWriteList 是一个线程安全的List实现,底层使用go 切片 +.在写入时,会复制一份新的切片,写入完成后,再将新的切片赋值给原来的切片. +在读取时,直接读取原来的切片 + +## 源码 +- [https://github.com/duke-git/lancet/blob/main/datastructure/list/copyonwritelist.go](https://github.com/duke-git/lancet/blob/main/datastructure/list/copyonwritelist.go) + +## 用法 +```go +import ( +"github.com/duke-git/lancet/datastructure/list" +) + +``` + +
+ +## 目录 +- [NewCopyOnWriteList](#NewCopyOnWriteList) +- [Size](#Size) +- [Get](#Get) +- [Set](#Set) +- [Remove](#Remove) +- [IndexOf](#IndexOf) +- [LastIndexOf](#LastIndexOf) +- [IsEmpty](#IsEmpty) +- [Contain](#Contain) +- [ValueOf](#ValueOf) +- [Add](#Add) +- [AddAll](#AddAll) +- [AddByIndex](#AddByIndex) +- [DeleteAt](#DeleteAt) +- [DeleteIf](#DeleteIf) +- [DeleteBy](#DeleteBy) +- [DeleteRange](#DeleteRange) +- [Equal](#Equal) + + +## 文档 + +### NewCopyOnWriteList +返回一个具有空切片的CopyOnWriteList +```go +type CopyOnWriteList[T any] struct { + data []T + lock sync.Locker +} + +func NewCopyOnWriteList() *CopyOnWriteList + +``` +#### 示例 +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/datastructure/list" +) + +func main() { + l := list.NewCopyOnWriteList([]int{1,2,3}) + fmt.Println(l) +} + +``` +### Size +返回CopyOnWriteList的长度 +```go +func (l *CopyOnWriteList[T]) Size() int +``` +#### 示例 +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/datastructure/list" +) + +func main() { + l := list.NewCopyOnWriteList([]int{1,2,3}) + fmt.Println(l.Size()) +} + +``` + +### Get +返回列表中指定位置的元素 +```go +func (c *CopyOnWriteList[T]) Get(index int) *T +``` + +#### 示例 +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/datastructure/list" +) + +func main() { + l := list.NewCopyOnWriteList([]int{1,2,3}) + fmt.Println(l.Get(2)) +} + +``` + + +### Set +将此列表中指定位置的元素替换为指定元素。 +```go +func (c *CopyOnWriteList[T]) Set(index int, e T) (oldValue *T, ok bool) +``` + +#### 示例 +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/datastructure/list" +) + +func main() { + l := list.NewCopyOnWriteList([]int{1,2,3}) + fmt.Println(l.Set(2, 4)) +} + +``` +### Remove + +### IndexOf +返回列表中值的索引,如果没有找到返回-1 +```go +func (c *CopyOnWriteList[T]) IndexOf(e T) int +``` +#### 示例 +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/datastructure/list" +) + +func main() { + l := list.NewCopyOnWriteList([]int{1,2,3}) + fmt.Println(l.IndexOf(1)) +} + +``` + +### LastIndexOf +返回指定元素在此列表中最后出现的索引,如果此列表不包含该元素,则返回-1 + +```go +func (c *CopyOnWriteList[T]) LastIndexOf(e T) int +``` + +#### 示例 +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/datastructure/list" +) + +func main() { + l := list.NewCopyOnWriteList([]int{1,2,3,1}) + fmt.Println(l.LastIndexOf(1)) +} + +``` + +### IsEmpty +如果此列表不包含任何元素,则返回true。 +```go +func (c *CopyOnWriteList[T]) IsEmpty() bool +``` + +#### 示例 +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/datastructure/list" +) + +func main() { + l := list.NewCopyOnWriteList([]int{}) + fmt.Println(l.IsEmpty()) +} +``` + + + +### Contain +判断CopyOnWriteList是否包含某个元素 +```go +func (c *CopyOnWriteList[T]) Contain(e T) bool +``` +#### 示例 +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/datastructure/list" +) + +func main() { + l := list.NewCopyOnWriteList([]int{1,2,3}) + fmt.Println(l.Contain(1)) +} +``` + + +### ValueOf +返回列表中索引处的值指针 +```go +func (c *CopyOnWriteList[T]) ValueOf(index int) []T +``` + +#### 示例 +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/datastructure/list" +) + +func main() { + l := list.NewCopyOnWriteList([]int{1,2,3}) + fmt.Println(l.ValueOf(2)) +} + +``` + +### Add +将指定的元素追加到此列表的末尾。 +```go +func (c *CopyOnWriteList[T]) Add(e T) bool +``` + +#### 示例 +```go + +package main + +import ( + "fmt" + "github.com/duke-git/lancet/datastructure/list" +) + +func main() { + l := list.NewCopyOnWriteList([]int{1,2,3}) + l.Add(4) + fmt.Println(l.getList()) +} + +``` + +### AddAll +将指定集合中的所有元素追加到此列表的末尾 +```go +func (c *CopyOnWriteList[T]) AddAll(e []T) bool +``` + +#### 示例 +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/datastructure/list" +) + +func main() { + l := list.NewCopyOnWriteList([]int{1,2,3}) + l.AddAll([]int{4,5,6}) + fmt.Println(l.getList()) +} + +``` + +### AddByIndex +将指定元素插入此列表中的指定位置 + +```go +func (c *CopyOnWriteList[T]) AddByIndex(index int, e T) bool +``` +#### 示例 +```go +package main +import ( + "fmt" + "github.com/duke-git/lancet/datastructure/list" +) +func main() { + l := list.NewCopyOnWriteList([]int{1,2,3}) + list.AddByIndex(2, 6) + fmt.Println(l.getList()) +} + +``` + +### DeleteAt +移除此列表中指定位置的元素。 +```go +func (c *CopyOnWriteList[T]) DeleteAt(index int) (oldValue *T, ok bool) +``` +#### 示例 +```go +package main +import ( + "fmt" + "github.com/duke-git/lancet/datastructure/list" +) + +func main() { + l := list.NewCopyOnWriteList([]int{1,2,3}) + list.DeleteAt(2) + fmt.Println(l.getList()) +} +``` + +### DeleteIf +从此列表中删除第一个出现的指定元素(如果该元素存在)。 +```go +func (c *CopyOnWriteList[T]) DeleteIf(f func(T) bool) (oldValue *T, ok bool) +``` +#### 示例 +```go +package main +import ( + "fmt" + "github.com/duke-git/lancet/datastructure/list" +) + +func main() { + l := list.NewCopyOnWriteList([]int{1,2,3}) + list.DeleteIf(func(i int) bool { + return i == 2 + }) + fmt.Println(l.getList()) +} +``` + +### DeleteBy +从此列表中删除第一个出现的指定元素(如果该元素存在)。 +```go +func (c *CopyOnWriteList[T]) DeleteBy(e T) (*T bool) +``` +#### 示例 +```go +package main +import ( + "fmt" + "github.com/duke-git/lancet/datastructure/list" +) + +func main() { + l := list.NewCopyOnWriteList([]int{1,2,3}) + list.DeleteBy(2) + fmt.Println(l.getList()) +} +``` + + +### DeleteRange +从该列表中删除索引介于fromIndex(包含)和toIndex(不包含)之间的所有元素。 +(左闭右开) +```go +func (c *CopyOnWriteList[T]) DeleteRange(start int, end int) +``` +#### 示例 +```go +package main +import ( + "fmt" + "github.com/duke-git/lancet/datastructure/list" +) + +func main() { + l := list.NewCopyOnWriteList([]int{1,2,3,4,5,6,7,8,9}) + list.DeleteRange(2, 5) + fmt.Println(l.getList()) +} +``` + +### Equal +如果指定的对象等于此列表,则返回true + +```go +func (c *CopyOnWriteList[T]) Equal(e []T) bool +``` +#### 示例 +```go +package main +import ( + "fmt" + "github.com/duke-git/lancet/datastructure/list" +) + +func main() { + l := list.NewCopyOnWriteList([]int{1,2,3,4,5,6,7,8,9}) + fmt.Println(l.Equal([]int{1,2,3,4,5,6,7,8,9})) +} +``` \ No newline at end of file