Golang实现hashmap
golang实现hashmap
思路:数组+链表->HashMap
先看一下go里的map是怎么实现的
go实现map采用拉链法的实现,如下图所示,键值对中的键会经过一个哈希函数,哈希函数会帮我们找到一个桶,对应我们用数组加链表的实现方式,就是映射到数组数组的一个位置,若该位置已经有数据了,那么就会将数据添加到该位置的链表中。
HashMap实现
我的实现思路其实跟go的map实现思路类似,用数组+链表来模拟拉链法的实现。具体代码:
/**
*
* hashMap的golang实现
*
**/
package main
//桶的格子数
const BucketsCount = 20
//node节点
type Node struct {
Next *Node
Data Value
}
//node节点存放的实际对象
type Value struct {
Key string
Value interface{}
}
//hashMap 桶
type HashMap struct {
Buckets [BucketsCount]*Node //存在node节点的数组
}
//新建一个hashMap桶
func NewHashMap() HashMap {
hashMap := HashMap{}
for i := 0; i < BucketsCount; i++ {
hashMap.Buckets[i] = NewEmptyNode()
}
return hashMap
}
//自定义hash算法获取key
func getBucketKey(key string) int {
length := len(key)
sum := 0
for i := 0; i < length; i++ {
sum = sum + int(key[i])
}
return sum % BucketsCount
}
//在hashMap桶中新加一个节点
func (h *HashMap) put(data Value) {
//获取index
index := getBucketKey(data.Key)
node := h.Buckets[index]
//判断数组节点是否是空节点
if node.Data.Value == nil {
node.Data = data
} else {
//发生了hash碰撞,往该槽的链表尾巴处添加存放该数据对象的新节点
last := node
for last.Next != nil {
last = last.Next
}
newNode := &Node{Data: data, Next: nil}
last.Next = newNode
}
}
//从hashMap中获取某个key的值
func (h *HashMap) get(key string) interface{} {
//获取index
index := getBucketKey(key)
if h.Buckets[index].Data.Key == key {
return h.Buckets[index].Data.Value
}
if h.Buckets[index].Next == nil {
return nil
}
next := h.Buckets[index].Next
for {
if next.Data.Key == key {
return next.Data.Value
}
if next.Next == nil {
return nil
}
next = next.Next
}
return nil
}
//创建一个空node
func NewEmptyNode() *Node {
node := &Node{}
node.Data.Key = ""
node.Data.Value = nil
node.Next = nil
return node
}
func main() {
myMap := NewHashMap()
data1 := Value{"001", 1}
myMap.put(data1)
data2 := Value{"002", "this is string"}
myMap.put(data2)
fmt.Println(myMap.get("002"))
}