欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Golang HashMap實現(xiàn)原理解析

 更新時間:2025年04月26日 11:43:15   作者:恒嘉宇  
HashMap是一種基于哈希表實現(xiàn)的鍵值對存儲結構,它通過哈希函數(shù)將鍵映射到數(shù)組的索引位置,支持高效的插入、查找和刪除操作,這篇文章主要介紹了Golang HashMap實現(xiàn)原理,需要的朋友可以參考下

  • HashMap是一種基于哈希表實現(xiàn)的鍵值對存儲結構,它通過哈希函數(shù)將鍵映射到數(shù)組的索引位置,支持高效的插入、查找和刪除操作。其核心原理如下:
    • 哈希函數(shù):將鍵轉換為數(shù)組索引。理想情況下,不同鍵應映射到不同索引,但沖突難以避免。
    • 數(shù)組+鏈表:使用數(shù)組作為桶(Bucket),每個桶是一個鏈表,解決哈希沖突(鏈地址法)。
    • 動態(tài)擴容:當元素數(shù)量超過容量與負載因子的乘積時,擴容并重新分配元素,保持操作高效性。
package main
import "fmt"
// Entry 鍵值對鏈表節(jié)點
type Entry struct {
    Key   string
    Value interface{}
    Next  *Entry
}
// HashMap 哈希表結構
type HashMap struct {
    buckets    []*Entry // 桶數(shù)組
    capacity   int      // 初始容量
    size       int      // 元素數(shù)量
    loadFactor float64  // 負載因子
}
// NewHashMap 初始化哈希表
func NewHashMap(capacity int) *HashMap {
    return &HashMap{
        buckets:    make([]*Entry, capacity),
        capacity:   capacity,
        loadFactor: 0.75,
    }
}
// hash 哈希函數(shù)(FNV-1a算法)
func (h *HashMap) hash(key string) int {
    const (
        offset = 2166136261
        prime  = 16777619
    )
    hash := offset
    for _, c := range key {
        hash ^= int(c)
        hash *= prime
    }
    return hash
}
// getIndex 計算鍵對應的桶索引
func (h *HashMap) getIndex(key string) int {
    return h.hash(key) % h.capacity
}
// Put 插入鍵值對
func (h *HashMap) Put(key string, value interface{}) {
    if float64(h.size)/float64(h.capacity) >= h.loadFactor {
        h.resize()
    }
    index := h.getIndex(key)
    entry := h.buckets[index]
    // 遍歷鏈表查找鍵是否存在
    for entry != nil {
        if entry.Key == key {
            entry.Value = value // 存在則更新
            return
        }
        entry = entry.Next
    }
    // 不存在則插入鏈表頭部
    h.buckets[index] = &Entry{
        Key:   key,
        Value: value,
        Next:  h.buckets[index],
    }
    h.size++
}
// Get 獲取值
func (h *HashMap) Get(key string) (interface{}, bool) {
    index := h.getIndex(key)
    entry := h.buckets[index]
    for entry != nil {
        if entry.Key == key {
            return entry.Value, true
        }
        entry = entry.Next
    }
    return nil, false
}
// Delete 刪除鍵
func (h *HashMap) Delete(key string) bool {
    index := h.getIndex(key)
    entry := h.buckets[index]
    var prev *Entry
    for entry != nil {
        if entry.Key == key {
            if prev == nil {
                h.buckets[index] = entry.Next // 刪除頭節(jié)點
            } else {
                prev.Next = entry.Next // 中間或尾部節(jié)點
            }
            h.size--
            return true
        }
        prev = entry
        entry = entry.Next
    }
    return false
}
// resize 擴容哈希表
func (h *HashMap) resize() {
    newCapacity := h.capacity * 2
    newBuckets := make([]*Entry, newCapacity)
    for i := 0; i < h.capacity; i++ {
        entry := h.buckets[i]
        for entry != nil {
            next := entry.Next
            newIndex := h.hash(entry.Key) % newCapacity // 重新計算索引
            entry.Next = newBuckets[newIndex]          // 插入新桶頭部
            newBuckets[newIndex] = entry
            entry = next
        }
    }
    h.buckets = newBuckets
    h.capacity = newCapacity
}
func main() {
    hm := NewHashMap(2) // 初始容量設為2便于觸發(fā)擴容
    hm.Put("name", "Alice")
    hm.Put("age", 30)
    hm.Put("lang", "Go") // 觸發(fā)擴容
    if val, ok := hm.Get("name"); ok {
        fmt.Println("name:", val) // 輸出 Alice
    }
    hm.Delete("age")
    if _, ok := hm.Get("age"); !ok {
        fmt.Println("age deleted") // 輸出此句
    }
}

到此這篇關于Golang HashMap實現(xiàn)原理的文章就介紹到這了,更多相關goland hashmap原理內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 關于Go 是傳值還是傳引用?

    關于Go 是傳值還是傳引用?

    這篇文章主要討論Go語言 是傳值還是傳引用?文章先從Go 官方的定義展開,隨后是傳值和傳引用得介紹到map 和 slice得區(qū)別,需要的小伙伴可以參考一下文章得具體內容
    2021-10-10
  • Golang 使用map需要注意的幾個點

    Golang 使用map需要注意的幾個點

    這篇文章主要介紹了Golang 使用map需要注意的幾個點,幫助大家更好的理解和學習golang,感興趣的朋友可以了解下
    2020-09-09
  • Go語言標準錯誤error全面解析

    Go語言標準錯誤error全面解析

    Go語言中的錯誤處理是通過內置的error接口來實現(xiàn)的,其中errorString和wrapError是兩種常見的錯誤類型實現(xiàn)方式,errorString通過errors.New()方法實現(xiàn),而wrapError則通過fmt.Errorf()方法實現(xiàn),支持錯誤的嵌套和解析
    2024-10-10
  • Golang中gin框架綁定解析json數(shù)據(jù)的兩種方法

    Golang中gin框架綁定解析json數(shù)據(jù)的兩種方法

    本文介紹 Golang 的 gin 框架接收json數(shù)據(jù)并解析的2種方法,文中通過代碼示例介紹的非常詳細,對大家的學習或工作有一定的幫助,需要的朋友可以參考下
    2023-12-12
  • Go語言中的錯誤處理最佳實踐詳解

    Go語言中的錯誤處理最佳實踐詳解

    這篇文章主要為大家詳細介紹了Go語言中的錯誤處理的相關知識,文中的示例代碼講解詳細,對我們深入了解Go語言有一定的幫助,需要的可以參考下
    2023-08-08
  • golang 中signal包的Notify用法說明

    golang 中signal包的Notify用法說明

    這篇文章主要介紹了golang 中signal包的Notify用法說明,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-03-03
  • Golang::slice和nil的對比分析

    Golang::slice和nil的對比分析

    這篇文章主要介紹了Golang::slice和nil的對比分析,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • Golang獲取目錄下的文件及目錄信息操作

    Golang獲取目錄下的文件及目錄信息操作

    這篇文章主要介紹了Golang獲取目錄下的文件及目錄信息操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • Go 中實現(xiàn)超時控制的方案

    Go 中實現(xiàn)超時控制的方案

    這篇文章主要介紹了Go 里的超時控制實現(xiàn)方案,本文給大家?guī)韮煞N解決方案,第一種方案是 Time.After(d Duration),第二種方案是利用 context,go 的 context 功能強大,本文通過實例代碼給大家介紹的非常詳細,感興趣的朋友跟隨小編一起看看吧
    2021-10-10
  • Go語言基礎if條件語句用法及示例詳解

    Go語言基礎if條件語句用法及示例詳解

    這篇文章主要為大家介紹了Go語言基礎if條件語句的用法及示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步早日升職加薪
    2021-11-11

最新評論