JS数据结构之 Map

Map介绍

Map(映射)是ES6引入的一种数据结构。这是一种存储键值对列表很方便的方法,类似于其他编程语言的哈希表。

HashMap(哈希表),也叫做散列表。是根据关键码值 key -> value而直接进行访问的数据结构。它通过把关键码值映射到表中一个位置来访问记录,有一点儿类似数组,但能以O(1)的时间复杂度查找到元素。

JS的对象Object,本质上是键值对的集合(Hash结构),但是传统上只能用字符串当作键,给使用带来了很大的限制。为了解决这个限制,ES6引入了Map的数据结构,它类似于对象,也是键值对的集合,但是键的范围不仅仅局限于字符串,而是各种类型的值(包括对象)都可以当作键,是一种更加完善的Hash结构的实现。

常用的Map方法有:

赋值 set(key, value)

获取 get(key)

移除指定键名及其对应的值 delete(key)

判断是否存在 has(key)

获取所有值 values()

key/value 迭代器 entries()

清空所有键值对 clear()

Map的数据转换:

Map转为数组:

const map_test = new Map();
console.log([...map_test]);

Map转为对象:

function mapToObj(map) {
const obj = Object.create(null);
map.forEach((v,k)=>{
obj[k] = v;
});
return obj;
}
const map_test = new Map();
console.log(mapToObj(map_test));

Map转为JSON

function mapToObj(map) {
const obj = Object.create(null);
map.forEach((v,k)=>{
obj[k] = v;
});
return obj;
} function mapToJson(map){
return JSON.stringify(mapToObj(map));
} const map_test = new Map();
console.log(mapToJson(map_test));

对象转为Map

const object_test = {}
console.log(new Map(Object.entries(page_info)));

数组转Map

const array_test = new Array();
console.log(new Map(array_test));

HashMap 和 Array 有什么区别?

查找效率:

  • HashMap因为是根据hashcode的值直接算出来index,所以查找效率是随着长度的增大而增加的。
  • ArrayMap使用的是二分法查找,所以当数组长度每增加一倍的时候,就需要多进行一次判断,效率下降。

扩容数量:

  • HashMap初始值16个长度,每次扩容的时候,直接申请双倍的数组空间
  • ArrayMap每次扩容的时候,如果size长度大于8时申请size*1.5个长度,大于4小于8时申请8个,小于4时申 请4个。这样比较ArrayMap其实是申请了更少的内存空间,但是扩容的频率会更高。因此,如果数据量比较大的时候,还是使用HashMap更合适,因为其扩容的次数要比ArrayMap少很多。

扩容效率:

  • HashMap每次扩容的时候重新计算每个数组成员的位置,然后放到新的位置。
  • ArrayMap则是直接使用System.arraycopy,所以效率上肯定是ArrayMap更占优势。

内存消耗:

  • 以ArrayMap采用了一种独特的方式,能够重复的利用因为数据扩容而遗留下来的数组空间,方便下一个ArrayMap的使用。而HashMap没有这种设计。 由于ArrayMap之缓存了长度是4和8的时候,所以如果频繁的使用到Map,而且数据量都比较小的时候,ArrayMap无疑是相当的是节省内存的。

总结:

综上所述,数据量比较小,并且需要频繁的使用Map存储数据的时候,推荐使用ArrayMap。 而数据量比较大的 时候,则推荐使用HashMap。

HashMap 和 Object 有什么区别?

Objects和Maps它们都允许你按键存取一个值、删除键、检测一个键是否绑定了值。

因此(并且也没有其他内建的替代方式了)过去我们一直都把对象当成Maps使用。

不过Maps和Objects有一些重要的区别,在下列情况里使用Map会是更好的选择:

Map Object
意外的键 Map默认情况不包含任何键。只包含显式插入的键。 一个Object有一个原型, 原型链上的键名有可能和你自己在对象上的设置的键名产生冲突。注意: 虽然 ES5 开始可以用Object.create(null)来创建一个没有原型的对象,但是这种用法不太常见。
键的类型 一个Map的键可以是任意值,包括函数、对象或任意基本类型。 一个Object的键必须是一个 String 或是Symbol。
键的顺序 Map中的 key 是有序的。因此,当迭代的时候,一个Map对象以插入的顺序返回键值。 一个Object的键是无序的注意:自ECMAScript 2015规范以来,对象确实保留了字符串和Symbol键的创建顺序; 因此,在只有字符串键的对象上进行迭代将按插入顺序产生键。
Size Map的键值对个数可以轻易地通过size 属性获取 Object的键值对个数只能手动计算
迭代 Map是 iterable 的,所以可以直接被迭代。 迭代一个Object需要以某种方式获取它的键然后才能迭代。
性能 在频繁增删键值对的场景下表现更好。 在频繁添加和删除键值对的场景下未作出优化。

JS数据结构之 Map的更多相关文章

  1. JS中的 map, filter, some, every, forEach, for in, for of 用法总结和区别

    JS中的 map, filter, some, every, forEach, for in, for of 用法总结和区别  :https://blog.csdn.net/hyupeng1006/a ...

  2. Javascript 如何生成Less和Js的Source map

    为什么有Source map CSS和JS脚本正变得越来越复杂,为了解决网络瓶颈,大部分源代码都需要经过编译.合并.压缩才能运用到实际环境中.为了减少网络资源占用,源码一般都会经过以下方式处理: 使用 ...

  3. ES6 之 Set数据结构和Map数据结构 Iterator和for...of循环

    ECMAScript 6 入门 Set数据结构 基本用法 ES6提供了新的数据结构Set.它类似于数组,但是成员的值都是唯一的,没有重复的值. Set本身是一个构造函数,用来生成Set数据结构. va ...

  4. 原生JS forEach()和map()遍历的区别以及兼容写法

    一.原生JS forEach()和map()遍历 共同点: 1.都是循环遍历数组中的每一项. 2.forEach() 和 map() 里面每一次执行匿名函数都支持3个参数:数组中的当前项item,当前 ...

  5. js实现的map方法

    /** * * 描述:js实现的map方法 * @returns {Map} */ function Map(){ var struct = function(key, value) { this.k ...

  6. echarts.js应用之map

    最近项目中用到了echarts.js中的map,我画了一个简版的案例,如下所示: 效果图: 主要代码如下: <!DOCTYPE html> <html lang="en&q ...

  7. js中的Map对象的简单示例

    es6提供一个对象Map, 其功能类似于java中的Map, 下面是java中的Map和js中的Map的简单对比: js中的Map.set()相当于java中的Map.put(), js中的Map.s ...

  8. 原生JS forEach()和map()遍历,jQuery$.each()和$.map()遍历

    一.原生JS forEach()和map()遍历 共同点: 1.都是循环遍历数组中的每一项. 2.forEach() 和 map() 里面每一次执行匿名函数都支持3个参数:数组中的当前项item,当前 ...

  9. JS数据结构第三篇---双向链表和循环链表之约瑟夫问题

    一.双向链表 在上文<JS数据结构第二篇---链表>中描述的是单向链表.单向链表是指每个节点都存有指向下一个节点的地址,双向链表则是在单向链表的基础上,给每个节点增加一个指向上一个节点的地 ...

随机推荐

  1. Python 用configparser读写ini文件

    一.configparser 简介Python用于读写ini文件的一个官方标准库.具体详见官网链接 二.configparser 部分方法介绍 方法 描述 read(filenames) filesn ...

  2. 什么是pytorch?

    Pytorch是基于python的科学计算包,为两类受众提供服务 作为Numpy的替换,让你可以使用GPU的算力 作为一个深度学习计算平台提供最大的计算灵活性与速度 开始体验pytorch的基础功能 ...

  3. 【主流技术】Redis 在 Spring 框架中的实践

    前言 在Java Spring 项目中,数据与远程数据库的频繁交互对服务器的内存消耗比较大,而 Redis 的特性可以有效解决这样的问题. Redis 的几个特性: Redis 以内存作为数据存储介质 ...

  4. ClickHouse(04)如何搭建ClickHouse集群

    ClickHouse集群的搭建和部署和单机的部署是类似的,主要在于配置的不一致,如果需要了解ClickHouse单机的安装设部署,可以看看这篇文章,ClickHouse(03)ClickHouse怎么 ...

  5. Ubuntu修改网卡名

    vim /etc/udev/rules.d/70-persistent-net.rules 添加以下内容: SUBSYSTEM=="net", ACTION=="add& ...

  6. 线程池ThreadPoolExector核心ctl, execute, addWorker, reject源码分析

    线程池核心方法execute()解析: public void execute(Runnable command) {//#1 if (command == null) throw new NullP ...

  7. intellidea 快捷键-*01

    快捷键: 0.竖向选择文本: alt+shift+insert:https://www.cnblogs.com/JonaLin/p/11422110.html 如果想修改快捷键(setting-> ...

  8. shell脚本语句

    条件语句 1.if语句 语法格式: if [ expression ] then 命令 elif [ expression ] then 命令 -- else 命令 fi if语句有单分支结构,双分支 ...

  9. TCP/IP协议三次握手、四次断开

    1.tcp报文格式 1行代表一个字节: 第一行:代表源端口和目的端口,分别占16位: 第二行:32位序列号:表示客户端向服务端发送的报文的序号是多少,这个序号是计算机随机生成的一个代表该报文的唯一标示 ...

  10. md 中超链接的解析问题:解析`this.$set()`,`$`前要加空格或转义符 `\`

    在用 Editor.md 写文档时,插入超链接,发现一个奇怪的现象: 要想正确显示超链接,必须在 $ 前加空格或转义符 \