完善: linkedlist
This commit is contained in:
121
map/linked_hashmap/linked_hashmap.go
Normal file
121
map/linked_hashmap/linked_hashmap.go
Normal file
@@ -0,0 +1,121 @@
|
||||
package linkedhashmap
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
linkedlist "github.com/474420502/focus/list/linked_list"
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
)
|
||||
|
||||
// LinkedHashmap
|
||||
type LinkedHashmap struct {
|
||||
list *linkedlist.LinkedList
|
||||
hmap map[interface{}]interface{}
|
||||
}
|
||||
|
||||
// New
|
||||
func New() *LinkedHashmap {
|
||||
lhmap := &LinkedHashmap{list: linkedlist.New(), hmap: make(map[interface{}]interface{})}
|
||||
return lhmap
|
||||
}
|
||||
|
||||
// PushBack if key exists, push value replace the value is exists. size is unchanging
|
||||
func (lhmap *LinkedHashmap) PushBack(key interface{}, value interface{}) {
|
||||
if _, ok := lhmap.hmap[key]; !ok {
|
||||
lhmap.list.PushBack(key)
|
||||
}
|
||||
lhmap.hmap[key] = value
|
||||
}
|
||||
|
||||
// PushFront if key exists, push value replace the value is exists. size is unchanging
|
||||
func (lhmap *LinkedHashmap) PushFront(key interface{}, value interface{}) {
|
||||
if _, ok := lhmap.hmap[key]; !ok {
|
||||
lhmap.list.PushFront(key)
|
||||
}
|
||||
lhmap.hmap[key] = value
|
||||
}
|
||||
|
||||
// Insert 如果成功在该位置返回True, 否则返回false
|
||||
func (lhmap *LinkedHashmap) Insert(idx uint, key interface{}, value interface{}) bool {
|
||||
if _, ok := lhmap.hmap[key]; !ok {
|
||||
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Get
|
||||
func (lhmap *LinkedHashmap) Get(key interface{}) (interface{}, bool) {
|
||||
value, ok := lhmap.hmap[key]
|
||||
return value, ok
|
||||
}
|
||||
|
||||
// Clear
|
||||
func (lhmap *LinkedHashmap) Clear() {
|
||||
lhmap.list.Clear()
|
||||
lhmap.hmap = make(map[interface{}]interface{})
|
||||
}
|
||||
|
||||
// Remove if key not exists reture nil, false.
|
||||
func (lhmap *LinkedHashmap) Remove(key interface{}) (interface{}, bool) {
|
||||
if v, ok := lhmap.hmap[key]; ok {
|
||||
delete(lhmap.hmap, key)
|
||||
lhmap.list.RemoveIf(func(idx uint, lkey interface{}) linkedlist.RemoveState {
|
||||
if lkey == key {
|
||||
return linkedlist.RemoveAndBreak
|
||||
}
|
||||
return linkedlist.UnremoveAndContinue
|
||||
})
|
||||
return v, true
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// RemoveIndex
|
||||
func (lhmap *LinkedHashmap) RemoveIndex(idx uint) (interface{}, bool) {
|
||||
if lhmap.list.Size() <= idx {
|
||||
panic(fmt.Sprintf("out of list range, size is %d, idx is %d", lhmap.list.Size(), idx))
|
||||
}
|
||||
|
||||
if _, ok := lhmap.hmap[key]; ok {
|
||||
delete(lhmap.hmap, key)
|
||||
lhmap.list.RemoveIf(func(idx uint, lkey interface{}) linkedlist.RemoveState {
|
||||
if lkey == key {
|
||||
return linkedlist.RemoveAndBreak
|
||||
}
|
||||
return linkedlist.UnremoveAndContinue
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Empty returns true if map does not contain any elements
|
||||
func (lhmap *LinkedHashmap) Empty() bool {
|
||||
return lhmap.Size() == 0
|
||||
}
|
||||
|
||||
// Size returns number of elements in the map.
|
||||
func (lhmap *LinkedHashmap) Size() uint {
|
||||
return lhmap.list.Size()
|
||||
}
|
||||
|
||||
// Keys returns all keys left to right (head to tail)
|
||||
func (lhmap *LinkedHashmap) Keys() []interface{} {
|
||||
return lhmap.list.Values()
|
||||
}
|
||||
|
||||
// Values returns all values in-order based on the key.
|
||||
func (lhmap *LinkedHashmap) Values() []interface{} {
|
||||
values := make([]interface{}, lhmap.Size())
|
||||
count := 0
|
||||
lhmap.list.Traversal(func(key interface{}) bool {
|
||||
values[count] = lhmap.hmap[key]
|
||||
count++
|
||||
return true
|
||||
})
|
||||
return values
|
||||
}
|
||||
|
||||
// String returns a string
|
||||
func (lhmap *LinkedHashmap) String() string {
|
||||
return spew.Sprint(lhmap.Values())
|
||||
}
|
||||
98
map/linked_hashmap/linked_hashmap_test.go
Normal file
98
map/linked_hashmap/linked_hashmap_test.go
Normal file
@@ -0,0 +1,98 @@
|
||||
package linkedhashmap
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestPush(t *testing.T) {
|
||||
lhm := New()
|
||||
lhm.PushFront(1, "1")
|
||||
lhm.PushBack("2", 2)
|
||||
var values []interface{}
|
||||
values = lhm.Values()
|
||||
|
||||
var testType reflect.Type
|
||||
|
||||
if testType = reflect.TypeOf(values[0]); testType.String() != "string" {
|
||||
t.Error(testType)
|
||||
}
|
||||
|
||||
if testType = reflect.TypeOf(values[1]); testType.String() != "int" {
|
||||
t.Error(testType)
|
||||
}
|
||||
|
||||
// 1 2
|
||||
lhm.PushFront(4, "4") // 4 1 2
|
||||
lhm.PushBack("3", 3) // 4 1 2 3
|
||||
|
||||
if lhm.String() != "[4 1 2 3]" {
|
||||
t.Error(lhm.String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestBase(t *testing.T) {
|
||||
lhm := New()
|
||||
for i := 0; i < 10; i++ {
|
||||
lhm.PushBack(i, i)
|
||||
}
|
||||
|
||||
if lhm.Empty() {
|
||||
t.Error("why lhm Enpty, check it")
|
||||
}
|
||||
|
||||
if lhm.Size() != 10 {
|
||||
t.Error("why lhm Size != 10, check it")
|
||||
}
|
||||
|
||||
lhm.Clear()
|
||||
if !lhm.Empty() {
|
||||
t.Error("why lhm Clear not Empty, check it")
|
||||
}
|
||||
|
||||
if lhm.Size() != 0 {
|
||||
t.Error("why lhm Size != 0, check it")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGet(t *testing.T) {
|
||||
lhm := New()
|
||||
for i := 0; i < 10; i++ {
|
||||
lhm.PushBack(i, i)
|
||||
}
|
||||
|
||||
for i := 0; i < 10; i++ {
|
||||
lhm.PushBack(i, i)
|
||||
}
|
||||
|
||||
if lhm.Size() != 10 {
|
||||
t.Error("why lhm Size != 10, check it")
|
||||
}
|
||||
|
||||
for i := 0; i < 10; i++ {
|
||||
if v, ok := lhm.Get(i); !ok || v != i {
|
||||
t.Error("ok is ", ok, " get value is ", v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemove(t *testing.T) {
|
||||
lhm := New()
|
||||
for i := 0; i < 10; i++ {
|
||||
lhm.PushBack(i, i)
|
||||
}
|
||||
|
||||
var resultStr = "[0 1 2 3 4 5 6 7 8 9]"
|
||||
for i := 0; i < 10; i++ {
|
||||
if lhm.String() != resultStr {
|
||||
t.Error(lhm.String(), resultStr)
|
||||
}
|
||||
|
||||
lhm.Remove(i)
|
||||
if lhm.Size() != uint(9-i) {
|
||||
t.Error("why lhm Size != ", uint(9-i), ", check it")
|
||||
}
|
||||
|
||||
resultStr = resultStr[0:1] + resultStr[3:]
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user