一文搞懂Map与Set的用法和区别解析

目录
  • 前言
  • 1.基本概念
    • 1.1 Map(字典)
    • 1.2 Set(集合)
  • 2.基本使用
    • 2.1 Map 基本使用
    • 2.2 Set 基本使用
  • 3.Map和Set区别
  • 4.使用场景介绍
    • 4.1 Set对象使用场景
    • 4.2 Map对象使用场景
  • 5.思考点
  • 总结

前言

作为前端开发人员,我们最常用的一些数据结构就是 ObjectArray 之类的,毕竟它们使用起来非常的方便。往往有些刚入门的同学都会忽视 SetMap 这两种数据结构的存在,因为能用 setmap 实现的,基本上也可以使用对象或数组实现,而且还更简单。

但是,存在必然合理,当你真正了解 MapSet 之后,你就会发现它们原来时如此美好!

1.基本概念

我们先来了解以下 MapSet 的基本概念,这样才能帮助我们更好的使用。虽然我们通常把这两种数据结构混合着来讲,但事实上它们它们还是有挺大区别的!

1.1 Map(字典)

想要迅速了解一个新的数据结构或 API 是,查看官网是一个不错的选择。Map 在官网上也有解释,我们一起来看下。

官网解释:

Map 对象保存键值对,并且能够记住键的原始插入顺序。任何值(对象或者原始值)都可以作为一个键或一个值。

官网的这句话非常精炼,我们从上面这句话中总结如下几个关键词:

  • 键值对
  • 记住插入顺序
  • 任意值作为键

一看到键值对,难免会想到对象。事实确实如此,Map 与我们平常所用的对象非常类似,它是一种类对象的数据结构,所以我们通常称它为 Map 对象

但是我们可以把它说得更为官方一点:Map 字典。关于程序中字典的概念大家可以下去了解一下。

特点总结:

  • Map 对象这种数据结构和和对象类型,都已键值对的形式存储数据,即 key-vlue 形式。
  • Map 对象存储的数据是有序的,而我们平常使用的对象是无序的,所以通常当我们需要使用对象形式(键值对)存储数据且需要有序时,采用 Map 对象进行存储。
  • Map 对象的键值可以是任意类型,我们平时使用的对象只能使用字符串作为键。

1.2 Set(集合)

Map 类似,我们同样先来看一看官网是怎么解释 Set 这个数据结构的。

官网的解释:

Set 对象允许你存储任何类型的唯一值,无论是原始值或者是对象引用。

Set 的解释比 Map 的解释还要精炼,我们从中提取出几个关键词:

  • 任何类型
  • 唯一值

上面关键词中我们需要重点关注“唯一值”,这说明使用 Set 存储的数据是不会重复的,除此之外,Set 也是一个对象,但是它是一个类数组对象,也就是说它长得像数组,我们通常直接称它为 Set 对象。

当然也可以官方一点的称它:Set 集合

特点总结:

  • Set 对象是一个类数组对象,它长得就很像数组。
  • Set 对象存储的值是不重复的,所以我们通常使用它来实现数组去重。
  • Set 对象存储的数据不是键值对的形式,而且它可以存储任何类型的数据。

2.基本使用

我们平常使用 Array 或者 Object 的时候,都是直接采用[变量] = [][变量] = {}的形式来进行初始化。而这里我们所讲的 MapSet 数据结构它们都是以构造函数的形式出现的,所以我们通常使用 new Set()或者 new Map()的形式初始化的。

2.1 Map 基本使用

初始化 map 对象:

let myMap = new Map();

初始化 map 时传入数据:

由于 Map 对象是一个构造函数,所以我们在初始化的时候可以传入默认数据的,只不过我们需要注意传入默认数据的格式,它默认接收一个二维数组。

let defaultMap = new Map([['name', '张三'], ['age', 20]]);

打印出来看看结果:

插入数据:

myMap.set('name', '小猪课堂'); // 字符串作为键
myMap.set(12, '会飞的猪'); // number 类型作为键
myMap.set({}, '知乎'); // 对象类型作为键

我们先打印出来看看结果:

获取长度:

我们传统的对象可以通过 Object.key().length 来获取对象长度,而 map 对象自带 size 属性获取对象长度。

let myMapSize = myMap.size;

获取值:

let objKey = {};
myMap.set('name', '小猪课堂'); // 字符串作为键
myMap.set(12, '会飞的猪'); // number 类型作为键
myMap.set(objKey, '知乎'); // 对象类型作为键
let name = myMap.get('name');
let age = myMap.get(12);
let any = myMap.get(objKey);
console.log(name, age, any); // 小猪课堂 会飞的猪 知乎

上段代码中需要注意的是不能使用 myMap.get({})的形式获取数据,因为 objKey!=={}

删除某个值:

myMap.delete('name');

判断某个值是否存在:

myMap.has('name'); // 返回 bool 值

2.2 Set 基本使用

Set对象的使用方式和Map对象的使用方式非常的类似,只不过存储的数据格式不一样罢了。这里需要注意的Set对象存储的不是键值对形式,它只存储了值,没有键,就和数组类似。

初始化Set对象:

let mySet = new Set();

初始化Set对象带有默认值:

Map类似,Set初始化时也可以初始化默认数据。

let defaultSet = new Set(['张三', 12, true]);

一起来看看输出结果:

插入数据:

mySet.add(1);
mySet.add('小猪课堂');

打印结果:

获取长度:

let mySetSize = mySet.size;

获取值:

由于Set对象存储的不是键值对形式,所以未提供get方法获取值,我们通常遍历它获取值:

mySet.forEach((item) => {
  console.log(item)
})

删除某个值:

mySet.delete(1);

判断某个值是否存在:

mySet.has(1); // 返回Boolean值

3.Map和Set区别

如果我们学会了它们两者如何使用,或多或少都知道它们的区别在哪里,我们这里为大家总结一下它们的区别要点:

  • MapSet查找速度都非常快,时间复杂度为O(1),而数组查找的时间复杂度为O(n)
  • Map对象初始化的值为一个二维数组,Set对象初始化的值为一维数组。
  • Map对象和Set对象都不允许键重复(可以将Set对象的键想象成值)。
  • Map对象的键是不能改的,但是值能改,Set对象只能通过迭代器来更改值。

4.使用场景介绍

4.1 Set对象使用场景

数组去重

这是大家很熟悉的一种场景,使用Set对象的唯一性值特性方便的给我们数组去重。

代码如下:

let arr = [1, 2, 3, 4, 5, 6, 3, 2, 5, 3, 2];
console.log([...new Set(arr)]); // [1, 2, 3, 4, 5, 6]

需要注意的是Set对象是一个类数组,我们使用...扩展运算符将一个类数组转化为了一个真正的数组。

4.2 Map对象使用场景

数字类型充当键

代码如下:

let errors = new Map([
  [400, 'InvalidParameter'],
  [404, 'Not found'],
  [500, 'InternalError']
]);
console.log(errors);

输出结果:

我们可以使用Map对象建立一个请求状态码对象字典,因为状态码是数字类型,所以使用Map对象很合适。

除了该场景外,如果需要保证对象的顺序,那么也是可以使用Map对象的。

5.思考点

前面我们说SetMap的插入删除效率为什么很高呢?

这里简单讲一下,更加深入需要大家自己下去好好学习一下数据结构了。

简述原因:

mapset存储的所有元素都是以节点的方式来进行存储的,这种节点结构和链表有点类似。我们都知道链表的特点是插入和删除都非常快,时间复杂度为O(1),两个节点通过指针相连,删除或者增加元素时,我们只是重新更改了指针的指向,不想数组那样,掺入或删除之后需要重新排序。

总结

Set对象和Map对象有很多优点的,比如说性能比较好等等,我们需要一一去体会它们的优缺点。你不如在每次创建数据结构之前想一想:使用Object更好还是Map更好呢?使用Array更好还是Set更好呢? 当然,如果深究SetMap底层原理之后,你会发现它们的实现原理就是红黑树。

到此这篇关于一文搞懂Map与Set的用法和区别的文章就介绍到这了,更多相关Map与Set用法内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • ES6中Symbol、Set和Map用法详解

    本文实例讲述了ES6中Symbol.Set和Map用法.分享给大家供大家参考,具体如下: Symbol 1.Symbol 是 ES6 引入了一种新的原始数据类型,表示独一无二的值.它是 JavaScript 语言的第七种数据类型,前六种分别是:undefined.null.布尔值(Boolean).字符串(String).数值(Number).对象(Object): 2.Symbol 值通过Symbol函数生成,可以作为对象的属性名使用,保证不会与其他属性名产生冲突: let s = Symbo

  • js中Map和Set的用法及区别实例详解

    目录 首先了解一下 Map 再来了解一下 Set 总结Map和Set的区别 结语: 首先了解一下 Map Map 是一组键值对的结构,和 JSON 对象类似. (1) Map数据结构如下 这里我们可以看到的是Map的数据结构是一个键值对的结构 (2) key 不仅可以是字符串还可以是对象 var obj ={name:"小如",age:9} let map = new Map() map.set(obj,"111") 打印结果如下 (3) Map常用语法如下 //初

  • ES6教程之for循环和Map,Set用法分析

    本文实例讲述了ES6教程之for循环和Map,Set用法.分享给大家供大家参考,具体如下: 现在大家先想一想,如果要你遍历一个数组的元素,你会选择如何去做呢?一般都会想起for循环: for (var index = 0; index < myArray.length; index++) { console.log(myArray[index]); } 可惜我得告诉你,这个方法是二十年的人才应该使用的方法,在ES5中已经提出了更为简便的forEach方法,代码如下: myArray.forEac

  • ES6中Set和Map用法实例详解

    本文实例讲述了ES6中Set和Map用法.分享给大家供大家参考,具体如下: Set ES6提供了新的数据结构Set.它类似于数组,但是成员的值都是唯一的,没有重复的值. Set函数可以接受一个数组(或类似数组的对象)作为参数,用来初始化. // 例一 var set = new Set([1, 2, 3, 4, 4]); [...set] // [1, 2, 3, 4] var s = new Set(); [2, 3, 5, 4, 5, 2, 2].map(x => s.add(x)); fo

  • 一文搞懂Map与Set的用法和区别解析

    目录 前言 1.基本概念 1.1 Map(字典) 1.2 Set(集合) 2.基本使用 2.1 Map 基本使用 2.2 Set 基本使用 3.Map和Set区别 4.使用场景介绍 4.1 Set对象使用场景 4.2 Map对象使用场景 5.思考点 总结 前言 作为前端开发人员,我们最常用的一些数据结构就是 Object.Array 之类的,毕竟它们使用起来非常的方便.往往有些刚入门的同学都会忽视 Set 和 Map 这两种数据结构的存在,因为能用 set 和 map 实现的,基本上也可以使用对

  • 一文搞懂Spring中@Autowired和@Resource的区别

    目录 1.来源不同 2.依赖查找顺序不同 2.1 @Autowired 查找顺序 2.2 @Resource 查找顺序 2.3 查找顺序小结 3.支持的参数不同 4.依赖注入的支持不同 5.编译器提示不同 总结 @Autowired 和 @Resource 都是 Spring/Spring Boot 项目中,用来进行依赖注入的注解.它们都提供了将依赖对象注入到当前对象的功能,但二者却有众多不同,并且这也是常见的面试题之一,所以我们今天就来盘它. @Autowired 和 @Resource 的区

  • 一文搞懂Golang中iota的用法和原理

    目录 前言 iota的使用 iota在const关键字出现时将被重置为0 按行计数 所有注释行和空行全部忽略 跳值占位 多个iota 一行多个iota 首行插队 中间插队 没有表达式的常量定义复用上一行的表达式 实现原理 iota定义 const 前言 我们知道iota是go语言的常量计数器,只能在常量的const表达式中使用,在const关键字出现的时将被重置为0,const中每新增一行常量声明iota值自增1(iota可以理解为const语句块中的行索引),使用iota可以简化常量的定义,但

  • 一文搞懂Vue中computed和watch的区别

    目录 一.computed介绍 1.1.get 和 set 用法 1.2.计算属性缓存 二.watch介绍 三.两者区别 3.1.对于 computed 3.2.对于 watch 四.应用场景 一.computed介绍 computed 用来监控自己定义的变量,该变量在 data 内没有声明,直接在 computed 里面定义,页面上可直接使用. //基础使用 {{msg}} <input v-model="name" /> //计算属性 computed:{ msg:fu

  • 一文搞懂ES6中的Map和Set

    Map Map对象保存键值对.任何值(对象或者原始值) 都可以作为一个键或一个值.构造函数Map可以接受一个数组作为参数. Map和Object的区别 •一个Object 的键只能是字符串或者 Symbols,但一个Map 的键可以是任意值. •Map中的键值是有序的(FIFO 原则),而添加到对象中的键则不是. •Map的键值对个数可以从 size 属性获取,而 Object 的键值对个数只能手动计算. •Object 都有自己的原型,原型链上的键名有可能和你自己在对象上的设置的键名产生冲突.

  • 一文搞懂hashCode()和equals()方法的原理

    Java中的超类java.lang.Object 有两个非常重要的方法: public boolean equals(Object obj) public int hashCode() 这两个方法最开发者来说是十分重要的,必须清楚的理解,但实际上,甚至很多经验丰富的Java开发者有时候也没有真正搞清楚这两个方法的使用和原理.当我们自定义了对象,并且想要将自定义的对象加到Map中时,我们就必须对自定义的对象重写这两个方法,才能正确使用Map.我们接下来将用这篇文章指出在使用hashcode和equ

  • 一文搞懂Java中的反射机制

    前一段时间一直忙,所以没什么时间写博客,拖了这么久,也该更新更新了.最近看到各种知识付费的推出,感觉是好事,也是坏事,好事是对知识沉淀的认可与推动,坏事是感觉很多人忙于把自己的知识变现,相对的在沉淀上做的实际还不够,我对此暂时还没有什么想法,总觉得,慢慢来,会更快一点,自己掌握好节奏就好. 好了,言归正传. 反射机制是Java中的一个很强大的特性,可以在运行时获取类的信息,比如说类的父类,接口,全部方法名及参数,全部常量和变量,可以说类在反射面前已经衣不遮体了(咳咳,这是正规车).先举一个小栗子

  • 如何使用IDEA开发Spark SQL程序(一文搞懂)

    目录 前言 Spark SQL是什么 1.使用IDEA开发Spark SQL 1.1.指定列名添加Schema 1.2.通过StructType指定Schema 1.3.反射推断Schema–掌握 1.4.花式查询 1.5. 相互转化 1.6.Spark SQL完成WordCount(案例) 1.6.1.SQL风格 1.6.2.DQL风格 前言 大家好,我是DJ丶小哪吒,我又来跟你们分享知识了.对软件开发有着浓厚的兴趣.喜欢与人分享知识.做博客的目的就是为了能与 他 人知识共享.由于水平有限.博

  • 一文搞懂JMeter engine中HashTree的配置问题

    目录 一.前言 二.HashTree的用法 三.JMeter源码导出jmx脚本文件介绍 四.自定义HashTree生成JMeter脚本 一.前言 之前介绍了JMeter engine启动原理,但是里面涉及到HashTree这个类结构没有给大家详细介绍,这边文章就详细介绍JMeter engine里面的HashTree结构具体用来做什么 大家看到下面是JMeter控制台配置截图,是一个标准的菜单形式:菜单形式其实就类似于"树型"的数据结构,而HashTree其实就是一个树型数据结构 我们

  • 一文搞懂Codec2解码组件

    目录 1 前言 2 组件的创建 3 组件接口 4 组件运行原理 5 小结 1 前言 在本篇中,我们将关注Codec 2.0以下几个问题: 1.从顶而下,一个解码组件是如何创建的 2.组件的接口有哪些,分别是什么含义 3.组件是如何运行的,输入与输出的数据流是怎样的 2 组件的创建 CCodec在allocate中,通过CreateComponentByName创建了具体的解码组件. //android/frameworks/av/media/codec2/sfplguin/CCodec.cpp

随机推荐