在LeeCode刷题时,对Map这个数据结构有了新的认识,所以想聊聊Map这种数据结构
进入正题小插曲:认识一个事务或者东西,借助一些科学的方法论,会让我们的思路更清晰,认识更高效;下边就借助5W2H分析法
发明者用五个以W开头的英语单词和两个以H开头的英语单词进行设问,发现解决问题的线索,寻找发明思路,进行设计构思,从而搞出新的发明项目,这就叫做5W2H法。
(1)WHAT——是什么?目的是什么?做什么工作?
(2)WHY——为什么要做?可不可以不做?有没有替代方案?
(3)WHO——谁?由谁来做?
(4)WHEN——何时?什么时间做?什么时机最适宜?
(5)WHERE——何处?在哪里做?
(6)HOW——怎么做?如何提高效率?如何实施?方法是什么?
(7)HOWMUCH——多少?做到什么程度?数量如何?质量水平如何?费用产出如何?
引自美国陆军兵器修理部
5W2H给我们提供一种分析问题的思路,我们选择其中的几个W和H分析一下
Map是什么从标准(ECMA-)来说,他是一个构造函数,使用的时候需要使用new操作符;
从数据结构来说,它类似于对象,也是键值对的集合,但它是一个哈希表结构,是介于数组和链表之间在空间和时间上做了权衡的一种数据结构。
map的本质是允许你把某些额外的信息(值)关联到一个对象(键)上,而无需把这个信息放入对象本身。
包含的属性和方法Map.size:返回Map中的个数。
Map.prototype.set(key,value):设置键名key对应的键值为value。
Map.prototype.get(key):读取key对应的键值。
Map.prototype.has(key):判断某个键是否在当前Map对象之中。
Map.prototype.delete(key):删除某个键,返回布尔类型。
Map.prototype.clear(key):遍历Map的所有成员。
Map.prototype.has(key):遍历Map的所有成员。
Map.prototype.keys():返回键名的遍历器。
Map.prototype.values():返回键值的遍历器。
Map.prototype.entries():返回所有成员的遍历器。
Map.prototype.forEach():遍历Map的所有成员。
详细介绍可以参考阮一峰老师的博客地址或者MDN上关于Map的介绍
为什么会有Map传统的Object只能用字符串当作键(key)。这给它的使用带来了很大的限制。Map这种数据结构的“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键,所以它有比对象更广泛的使用范围。
什么时候用Map实际场景中用的确实不是很多,从概念上来说是在不确定键值对里面的键的名称的类型的时候,需要用Map。在实际项目中Map这种数据用的不是很多,但是在hash类算法中用的不少,像LeeCode中的49.字母异位词分组通过异位词建立hash的key进行分组,有兴趣可以了解一下。还有一些场景
Map反映出来的思想Map是一种散列的hash结构,在黄申老师的《程序员的数学基础课》中关于余数:原来取余操作本身就是个哈希函数中有详细的介绍
哈希(Hash)你应该不陌生,在每个编程语言中,都会有对应的哈希函数。哈希有的时候也会被翻译为散列,简单来说,它就是将任意长度的输入,通过哈希算法,压缩为某一固定长度的输出。这话听着是不是有点耳熟?我们上面的求余过程不就是在做这事儿吗?举个例子,假如你想要快速读写万条数据记录,要达到高速地存取,最理想的情况当然是开辟一个连续的空间存放这些数据,这样就可以减少寻址的时间。但是由于条件的限制,我们并没有能够容纳万条记录的连续地址空间,这个时候该怎么办呢?我们可以考察一下,看看系统是否可以提供若干个较小的连续空间,而每个空间又能存放一定数量的记录。比如我们找到了个较小的连续空间,也就是说,这些空间彼此之间是被分隔开来的,但是内部是连续的,并足以容纳1万条记录连续存放,那么我们就可以使用余数和同余定理来设计一个散列函数,并实现哈希表的结构。那这个函数应该怎么设计呢?你可以先停下来思考思考,提醒你下,你可以再想想星期几的那个例子,因为这里面用的就是余数的思想。
引自-《程序员的数学基础课》
很多事情都是相通的,在一些基础的思想上不断的迭代进化。
王英琦