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数据结构第二篇---链表>中描述的是单向链表.单向链表是指每个节点都存有指向下一个节点的地址,双向链表则是在单向链表的基础上,给每个节点增加一个指向上一个节点的地 ...
随机推荐
- 基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结
随着Vue3和TypeScript的大浪潮不断袭来,越来越多的Vue项目采用了TypeScript的语法来编写代码,而Vue3的JS中的Setup语法糖也越来越广泛的使用,给我们这些以前用弱类型的JS ...
- 【python】自动更新pu口袋校园活动
[python]自动更新pu口袋校园活动 脚本目标: 1. 自动爬取pu口袋校园活动,筛选出需要的活动,此处我的筛选条件是线上活动,因为可以不用去就可以白嫖学时 2. 自动发送邮件到QQ邮箱,每次只发 ...
- centos更改mac
centos 6更改mac vim /etc/udev/rules.d/70-persistent-net.rules
- 如何用 银行卡OCR 接口进行快速开发
最近公司项目有一个银行卡识别的小需求,想着如果用现成的API就可以大大提高开发效率,在网上的API商店搜索了一番,发现了 APISpace,它里面的银行卡OCR非常符合我的开发需求. 银行卡OCR ...
- jdbc 12: 模糊查询
jdbc连接mysql,进行模糊查询 package com.examples.jdbc.o11_模糊查询; import com.examples.jdbc.utils.DBUtils; impor ...
- Centos7借助docker部署mysql,提供远程链接服务
Centos7 借助docker部署mysql,并提供远程连接服务 安装docker 运行docker 注意安装docker和运行docker的步骤很简单,可以参考我学习docker的笔记 docke ...
- 【每天学一点-06】在Vue中使用Vant-Picker选择器,并且给选择器添加一个类似Antd-Select-showSearch的搜索功能
一.在Vant文档中,Picker组件的API中是没有showSearch这一选项的 1.Vant-Picker 文档 2.Antd-Select 文档 3.需要完成的需求 4.因为在H5项目中出现了 ...
- linux学习(小白篇)
当前服务器:centos 7 shell命令框:xshell 文件预览及上传:xftp (界面化软件,非常好用) 数据库连接:navicat 此文是在学习linux时做一个指令合集,方便自己查阅 进文 ...
- React报错之No duplicate props allowed
正文从这开始~ 总览 当我们为相同的组件传递相同的属性多次时,就会导致"No duplicate props allowed"警告.为了解决该警告,请确保只传递一次该属性.比如说, ...
- 用JavaScript写随机出一个颜色
function changeColor(){ var r = parseInt(Math.random()*255) var g = parseInt(Math.random()*255) var ...