focus/map/linked_hashmap/linked_hashmap.go
2019-07-19 19:05:35 +08:00

130 lines
3.3 KiB
Go

package linkedhashmap
import (
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
}
// Put equal to PushBack
func (lhmap *LinkedHashmap) Put(key interface{}, value interface{}) {
if _, ok := lhmap.hmap[key]; !ok {
lhmap.list.PushBack(key)
}
lhmap.hmap[key] = value
}
// PushBack equal to Put, 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 类似 linkedlist Size 可以 等于 idx
func (lhmap *LinkedHashmap) Insert(idx uint, key interface{}, value interface{}) bool {
if _, ok := lhmap.hmap[key]; !ok {
lhmap.list.Insert(idx, key)
lhmap.hmap[key] = value
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 {
// log.Printf("warn: out of list range, size is %d, idx is %d\n", lhmap.list.Size(), idx)
if key, ok := lhmap.list.Remove(idx); ok {
result := lhmap.hmap[key]
delete(lhmap.hmap, key)
return result, true
}
}
return nil, false
}
// RemoveIf 不是必须不实现这个
// func (lhmap *LinkedHashmap) RemoveIf(every func(idx uint, key interface{}) RemoveState) (interface{}, bool) {
// }
// 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())
}