map操作函数的定义和使用 map是什么意思

本文全面讲解 Go 语言的 map 相关知识,文章很长,建议您收藏,抽时间慢慢仔细阅读 。Go语言中文网,致力于每日分享编码知识,欢迎关注我,会有意想不到的收获!

map操作函数的定义和使用 map是什么意思


这篇文章主要讲 map 的赋值、删除、查询、扩容的具体执行过程,仍然是从底层的角度展开 。结合源码,看完本文一定会彻底明白 map 底层原理 。我要说明的是,这里对 map 的基本用法涉及比较少,我相信可以通过阅读其他入门书籍了解 。本文的内容比较深入,但是由于我画了各种图,我相信很容易看懂 。01什么是 map维基百科里这样定义 map:
In computer science, an associative array, map, symbol table, or dictionary is an abstract data type composed of a collection of (key, value) pairs, such that each possible key appears at most once in the collection.
简单说明一下:在计算机科学里,被称为相关数组、map、符号表或者字典,是由一组 <key, value> 对组成的抽象数据结构,并且同一个 key 只会出现一次 。有两个关键点:map 是由 key-value 对组成的;key 只会出现一次 。和 map 相关的操作主要是:
  1. 增加一个 k-v 对 —— Add or insert;
  2. 删除一个 k-v 对 —— Remove or delete;
  3. 修改某个 k 对应的 v —— Reassign;
  4. 查询某个 k 对应的 v —— Lookup;
简单说就是最基本的 增删查改 。map 的设计也被称为 “The dictionary problem”,它的任务是设计一种数据结构用来维护一个集合的数据,并且可以同时对集合进行增删查改的操作 。最主要的数据结构有两种:哈希查找表(Hash table)、搜索树(Search tree) 。哈希查找表用一个哈希函数将 key 分配到不同的桶(bucket,也就是数组的不同 index) 。这样,开销主要在哈希函数的计算以及数组的常数访问时间 。在很多场景下,哈希查找表的性能很高 。哈希查找表一般会存在“碰撞”的问题,就是说不同的 key 被哈希到了同一个 bucket 。一般有两种应对方法:链表法和开放地址法 。链表法将一个 bucket 实现成一个链表,落在同一个 bucket 中的 key 都会插入这个链表 。开放地址法则是碰撞发生后,通过一定的规律,在数组的后面挑选“空位”,用来放置新的 key 。搜索树法一般采用自平衡搜索树,包括:AVL 树,红黑树 。面试时经常会被问到,甚至被要求手写红黑树代码,很多时候,面试官自己都写不上来,非常过分 。自平衡搜索树法的最差搜索效率是 O(logN),而哈希查找表最差是 O(N) 。当然,哈希查找表的平均查找效率是 O(1),如果哈希函数设计的很好,最坏的情况基本不会出现 。还有一点,遍历自平衡搜索树,返回的 key 序列,一般会按照从小到大的顺序;而哈希查找表则是乱序的 。02为什么要用 map
map操作函数的定义和使用 map是什么意思


从 Go 语言官方博客摘录一段话:
One of the most useful data structures in computer science is the hash table. Many hash table implementations exist with varying properties, but in general they offer fast lookups, adds, and deletes. Go provides a built-in map type that implements a hash table.
hash table 是计算机数据结构中一个最重要的设计 。大部分 hash table 都实现了快速查找、添加、删除的功能 。Go 语言内置的 map 实现了上述所有功能 。很难想象写一个程序不使用 map,以至于在回答为什么要用 map 这个问题上犯了难 。所以,到底为什么要用 map 呢?因为它太强大了,各种增删查改的操作效率非常高 。03map 的底层如何实现首先声明我用的 Go 版本:go version go1.9.2 darwin/amd64前面说了 map 实现的几种方案,Go 语言采用的是哈希查找表,并且使用链表解决哈希冲突 。接下来我们要探索 map 的核心原理,一窥它的内部结构 。map 内存模型在源码中,表示 map 的结构体是 hmap,它是 hashmap 的“缩写”:

推荐阅读