JS数据结构之 Map
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的更多相关文章
- 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 ...
- Javascript 如何生成Less和Js的Source map
为什么有Source map CSS和JS脚本正变得越来越复杂,为了解决网络瓶颈,大部分源代码都需要经过编译.合并.压缩才能运用到实际环境中.为了减少网络资源占用,源码一般都会经过以下方式处理: 使用 ...
- ES6 之 Set数据结构和Map数据结构 Iterator和for...of循环
ECMAScript 6 入门 Set数据结构 基本用法 ES6提供了新的数据结构Set.它类似于数组,但是成员的值都是唯一的,没有重复的值. Set本身是一个构造函数,用来生成Set数据结构. va ...
- 原生JS forEach()和map()遍历的区别以及兼容写法
一.原生JS forEach()和map()遍历 共同点: 1.都是循环遍历数组中的每一项. 2.forEach() 和 map() 里面每一次执行匿名函数都支持3个参数:数组中的当前项item,当前 ...
- js实现的map方法
/** * * 描述:js实现的map方法 * @returns {Map} */ function Map(){ var struct = function(key, value) { this.k ...
- echarts.js应用之map
最近项目中用到了echarts.js中的map,我画了一个简版的案例,如下所示: 效果图: 主要代码如下: <!DOCTYPE html> <html lang="en&q ...
- js中的Map对象的简单示例
es6提供一个对象Map, 其功能类似于java中的Map, 下面是java中的Map和js中的Map的简单对比: js中的Map.set()相当于java中的Map.put(), js中的Map.s ...
- 原生JS forEach()和map()遍历,jQuery$.each()和$.map()遍历
一.原生JS forEach()和map()遍历 共同点: 1.都是循环遍历数组中的每一项. 2.forEach() 和 map() 里面每一次执行匿名函数都支持3个参数:数组中的当前项item,当前 ...
- JS数据结构第三篇---双向链表和循环链表之约瑟夫问题
一.双向链表 在上文<JS数据结构第二篇---链表>中描述的是单向链表.单向链表是指每个节点都存有指向下一个节点的地址,双向链表则是在单向链表的基础上,给每个节点增加一个指向上一个节点的地 ...
随机推荐
- Linux YUM yum 命令详解
Yum命令 常用yum命令列表 command is one of: * install package1 [package2] [...] * update [package1] [package2 ...
- 记一次 .NET 某工控数据采集平台 线程数 爆高分析
一:背景 1. 讲故事 前几天有位朋友在 B站 加到我,说他的程序出现了 线程数 爆高的问题,让我帮忙看一下怎么回事,截图如下: 说来也奇怪,这些天碰到了好几起关于线程数无缘无故的爆高,不过那几个问题 ...
- ArrayList集合概述和基本使用和ArrayList集合的常用方法和遍历
什么是ArrayList类 java.util.ArrayList 是大小可变的数组的实现,存储在内的数据称为元素.此类提供一些方法来操作内部存储 的元素. ArrayList 中可不断添加元素,其大 ...
- Solution -「HNOI2013」消毒
弱化一下,先考虑在二维上解决问题. 题目就转化为:有 \(n\) 个点 \((i, j)\) 需要被覆盖,而我们每次可以选一行或一列去覆盖,求覆盖所有点的最少选择次数. 如果我们对于每一个 \((i, ...
- 苹果手机和Windows之间互传文件
参考链接:https://jingyan.baidu.com/article/a378c960c46804f229283064.html 实现原理:就是使用Samba服务,windows共享一个文件夹 ...
- Unity3D学习笔记9——加载纹理
目录 1. 概述 2. 详论 2.1. Resources方式 2.2. API方式 2.3. Web方式 1. 概述 理论上,Unity中加载纹理并没有什么难度,只需要将图片放置在Assets文件夹 ...
- 重写Object的equals方法和Objects的equals方法
Object类的equals方法默认比较的是两个对象的地址值,没有意义 所以我们需要重写equals方法,比较两个对象的属性值(name,age等等): 对象的属性值一样返回true否则返回false ...
- 国产钡铼分布式IO模块如何与西门子PLC Profinet通讯
1.准备IO模块:耦合器BL200PN.数字量输出模块M2082.数字量输入M1081.模拟量输入模块M3401.模拟量输出M4043. 编辑搜图 请点击输入图片描述(最多18字) 2.BL200P ...
- 什么是双网口以太网IO模块
MXXXE系列远程IO模块工业级设计,适用于工业物联网和自动化控制系统,MxxxE工业以太网远程 I/O 配备 2 个mac层数据交换芯片的以太网端口,允许数据通过可扩展的菊花链以太网远程 I/O 阵 ...
- 四位一体水溶交融,Docker一拖三Tornado6.2 + Nginx + Supervisord非阻塞负载均衡容器式部署实践
原文转载自「刘悦的技术博客」https://v3u.cn/a_id_203 容器,又见容器.Docker容器的最主要优点就在于它们是可移植的.一套服务,其所有的依赖关系可以捆绑到一个独立于Linux内 ...