这是用Go实现的简单的Hash Map,类型是 string , string, 只实现了简单的 get、put、remove等方法,大家感兴趣的可以看一下。
后面会跟进完善它,并且实现并发安全 Hash Map以及支持 泛型 的Hash Map,下面上代码:
package HashMap
import (
"hash/crc32"
)
// map of string type
type StringMap interface {
Get(key string) string
Put(key string, value string)
}
/** simple hashMap of string map */
type HashMap struct {
StringMap
// size of map
size int
// data
elementData []*Entry
// load factor of map
loadFactor float32
// init size
defaultSize int
}
type Entry struct {
//
key string
//
value string
// hash of the entry
hash int
// next of the entry
next *Entry
}
// get hash value of key
func(h *HashMap) Hash(key string) int {
v := int(crc32.ChecksumIEEE([]byte(key)))
return v
}
// init map with
func(h *HashMap) initMap() {
h.defaultSize = 20
h.elementData = make([]*Entry, h.defaultSize)
}
// get elementData index by hash value
func (h *HashMap) indexByHash (hashValue int) int {
return hashValue & len(h.elementData)
}
func(h *HashMap) Put( key string, value string) {
if h.elementData==nil {
h.initMap()
}
hashValue := h.Hash(key)
index := h.indexByHash(hashValue)
entry := h.elementData[index]
if entry==nil {
// if key not exist, then put a new entry
newEntry := new(Entry)
newEntry.key = key
newEntry.value = value
newEntry.hash = hashValue
h.elementData[index] = newEntry
h.size++
}else{
// if key exist replace value
for{
if entry.key==key && entry.hash==hashValue {
entry.value = value
h.size++
}else {
entry = entry.next
if entry==nil {
break
}
}
}
}
}
func(h *HashMap) Get(key string) string {
hashValue := h.Hash(key)
index := h.indexByHash(hashValue)
entry := h.elementData[index]
if entry==nil {
return ""
}
for{
if entry.key==key && entry.hash==hashValue {
return entry.value
}else {
entry = entry.next
if entry==nil {
return ""
}
}
}
}
// remove key if exist find it return true else false
func(h *HashMap) Remove(key string) bool {
hashValue := h.Hash(key)
index := h.indexByHash(hashValue)
entry := h.elementData[index]
if entry==nil {
return false
}else {
for{
var pre *Entry
if entry.hash==hashValue {
// entry is first node
if pre==nil {
next := entry.next
h.elementData[index] = next
}else{ // entry has pre node
pre.next = entry.next
}
h.size--
return true
}else {
pre = entry
entry = entry.next
}
}
}
}
func(h *HashMap) Size() int {
return h.size
}
测试代码:
func useMap() {
m := new(HashMap.HashMap)
m.Put("a", "AAA")
m.Put("b", "BBB")
valueA :=m.Get("a")
valueB :=m.Get("b")
valueC :=m.Get("c")
fmt.Printf("value of a is %s\n", valueA)
fmt.Printf("value of b is %s\n", valueB)
fmt.Printf("value of c is %s\n", valueC)
removeA := m.Remove("a")
fmt.Printf("remove a return %t\n", removeA)
removeC := m.Remove("c")
fmt.Printf("remove c return %t\n", removeC)
}
func main() {
useMap()
}
测试结果:"c" 由于没有put,所有返回为"" 空字符串,remove方法 同理