Set中的add()方法和数组的push()方法有什么区别?

简介: Set中的add()方法和数组的push()方法有什么区别?

在 JavaScript 中,Setadd() 方法和数组的 push() 方法都可用于添加元素,但它们在数据结构、功能和行为上存在本质区别。以下是详细对比:

一、核心区别概览

特性 Set.prototype.add() Array.prototype.push()
数据结构 无序唯一值集合(无索引) 有序列表(有索引)
重复元素处理 自动过滤重复值(基于 === 允许添加重复值
返回值 返回 Set 本身(支持链式调用) 返回新数组长度
元素顺序 按添加顺序排列(遍历时保持) 按插入位置排序(索引决定顺序)
性能(大数据量) 插入/查找效率高(O(1) 时间复杂度) 插入效率低(尾部 O(1),中间/头部 O(n))
访问方式 无索引,通过 has() 检查存在性 通过索引访问元素(如 arr[0]

二、具体差异详解

1. 重复元素处理

  • Set.add():自动去重,确保元素唯一性。

    const set = new Set();
    set.add(1).add(1); // 第二次添加无效
    console.log([...set]); // [1]
    
  • Array.push():允许重复元素。

    const arr = [];
    arr.push(1, 1);
    console.log(arr); // [1, 1]
    

2. 返回值与链式调用

  • Set.add():返回 Set 本身,支持链式调用。

    const set = new Set();
    set.add(1).add(2).add(3); // 链式添加
    
  • Array.push():返回新数组长度。

    const arr = [];
    const length = arr.push(1, 2);
    console.log(length); // 2
    

3. 元素顺序与访问

  • Set:无索引,遍历顺序由添加顺序决定。

    const set = new Set();
    set.add(3).add(1).add(2);
    console.log([...set]); // [3, 1, 2](按添加顺序)
    
  • Array:依赖索引,可随机访问。

    const arr = [];
    arr.push(3, 1, 2);
    console.log(arr[1]); // 1(按索引访问)
    

4. 性能差异

  • Set:插入和查找元素的时间复杂度为 O(1),适合频繁检查元素存在性的场景。

    // 检查元素是否存在
    console.log(set.has(1)); // O(1)
    
  • Array:检查元素存在性需遍历数组(如 includes()),时间复杂度为 O(n)。

    console.log(arr.includes(1)); // O(n)
    

三、应用场景对比

场景 推荐使用 Set 推荐使用 Array
存储唯一值集合 ✅ 自动去重 ❌ 需手动检查重复
频繁检查元素存在性 ✅ O(1) 时间复杂度 ❌ O(n) 时间复杂度
需要按索引随机访问元素 ❌ 无索引支持 ✅ 索引访问高效
维护元素插入顺序 ✅ 遍历时保持添加顺序 ✅ 索引严格控制顺序
处理大数据量 ✅ 插入/删除效率高 ❌ 中间插入/删除性能较差

四、示例对比

1. 数组去重

// 使用 Set
const uniqueArray = [...new Set([1, 2, 2, 3])];
console.log(uniqueArray); // [1, 2, 3]

// 使用 Array(手动去重)
const arr = [1, 2, 2, 3];
const unique = arr.filter((item, index) => arr.indexOf(item) === index);
console.log(unique); // [1, 2, 3](代码更复杂)

2. 检查元素存在性

// Set 更高效
const set = new Set([1, 2, 3]);
console.log(set.has(2)); // true(O(1))

// Array 需遍历
const arr = [1, 2, 3];
console.log(arr.includes(2)); // true(O(n))

3. 维护有序列表

// Array 更适合
const arr = [];
arr.push(3);
arr.push(1);
console.log(arr[0]); // 3(按索引访问)

// Set 无法通过索引访问
const set = new Set();
set.add(3).add(1);
// 需遍历获取元素,无直接索引访问方式

五、总结:如何选择?

  • 使用 Set

    • 需要元素唯一性。
    • 频繁检查元素存在性。
    • 无需按索引访问,只需遍历。
  • 使用 Array

    • 需要维护元素顺序(通过索引控制)。
    • 允许重复元素。
    • 需要随机访问或操作特定位置的元素(如 splice()map() 等)。

理解两者差异后,可根据具体需求灵活选择数据结构,提升代码效率和可读性。

相关文章
|
1月前
|
存储 安全 JavaScript
如何使用Set的add()方法添加元素?
如何使用Set的add()方法添加元素?
211 58
|
1月前
|
存储 安全 JavaScript
如何使用Set的delete()方法删除元素?
如何使用Set的delete()方法删除元素?
122 10
|
1月前
|
存储 编译器 容器
set、map、multiset、multimap的介绍及使用以及区别,注意事项
set是按照一定次序存储元素的容器,使用set的迭代器遍历set中的元素,可以得到有序序列。set当中存储元素的value都是唯一的,不可以重复,因此可以使用set进行去重。set默认是升序的,但是其内部默认不是按照大于比较,而是按照小于比较。set中的元素不能被修改,因为set在底层是用二叉搜索树来实现的,若是对二叉搜索树当中某个结点的值进行了修改,那么这棵树将不再是二叉搜索树。
47 0
|
7月前
|
Java Maven Spring
【SpringBug】lombok插件失效,但是没有报错信息,@Data不能生成get和set方法
解决写了@Data注解,但是在测试文件中生成的反编译target文件Us二Info中没有get和set方法
588 16
|
8月前
|
Java Windows
IDEA不使用lombok,如何快速生成get和set方法
【11月更文挑战第10天】在 IntelliJ IDEA 中生成 `get` 和 `set` 方法有多种方式:通过菜单操作、使用快捷键或自定义模板。菜单操作包括选择“Code”菜单中的“Generate...”,快捷键为“Alt + Insert”。自定义模板可在“File”->“Settings”->“Editor”->“Code Style”->“Java”中设置。批量生成时,可多选变量一次性生成。
1138 2
|
9月前
|
Rust Java
set 方法是坏味道?
【10月更文挑战第19天】
90 5
|
4月前
|
编译器 C++ 容器
【c++丨STL】基于红黑树模拟实现set和map(附源码)
本文基于红黑树的实现,模拟了STL中的`set`和`map`容器。通过封装同一棵红黑树并进行适配修改,实现了两种容器的功能。主要步骤包括:1) 修改红黑树节点结构以支持不同数据类型;2) 使用仿函数适配键值比较逻辑;3) 实现双向迭代器支持遍历操作;4) 封装`insert`、`find`等接口,并为`map`实现`operator[]`。最终,通过测试代码验证了功能的正确性。此实现减少了代码冗余,展示了模板与仿函数的强大灵活性。
110 2
|
1月前
|
存储 JavaScript 前端开发
for...of循环在遍历Set和Map时的注意事项有哪些?
for...of循环在遍历Set和Map时的注意事项有哪些?
48 0
|
1月前
|
存储 C++ 容器
unordered_set、unordered_multiset、unordered_map、unordered_multimap的介绍及使用
unordered_set是不按特定顺序存储键值的关联式容器,其允许通过键值快速的索引到对应的元素。在unordered_set中,元素的值同时也是唯一地标识它的key。在内部,unordered_set中的元素没有按照任何特定的顺序排序,为了能在常数范围内找到指定的key,unordered_set将相同哈希值的键值放在相同的桶中。unordered_set容器通过key访问单个元素要比set快,但它通常在遍历元素子集的范围迭代方面效率较低。它的迭代器至少是前向迭代器。前向迭代器的特性。
64 0
|
1月前
|
编译器 C++ 容器
用一棵红黑树同时封装出map和set
再完成上面的代码后,我们的底层代码已经完成了,这时候已经是一个底层STL的红黑树了,已经已符合库里面的要求了,这时候我们是需要给他穿上对应的“衣服”,比如穿上set的“衣服”,那么这个穿上set的“衣服”,那么他就符合库里面set的要求了,同样map一样,这时候我们就需要实现set与map了。因此,上层容器map需要向底层红黑树提供一个仿函数,用于获取T当中的键值Key,这样一来,当底层红黑树当中需要比较两个结点的键值时,就可以通过这个仿函数来获取T当中的键值了。我们就可以使用仿函数了。
28 0