不能用数组代替Set去重,因数组不自动去重、查存复杂度O(n)且对象比较易错;Set增删查为O(1)、语义清晰、NaN相等、引用一致,支持交差集等操作但需手动实现。

JavaScript 的 Set 是一个内置构造函数,用来存储唯一值(重复值自动被忽略),不是数组,也没有索引,但支持遍历和常见集合操作。
为什么不能用数组代替 Set 去去重?
数组本身不阻止重复,每次去重都要手动 filter + indexOf 或用 new Set(arr) 转换——后者更简洁、语义更准。更重要的是:Set 的 add、has 平均时间复杂度是 O(1),而数组的 includes 是 O(n);尤其在频繁查存的场景(如实时过滤、状态标记),性能差距明显。
常见错误现象:arr.includes(obj) 总返回 false,因为对象比较是引用相等;而 set.has(obj) 同样基于引用,但至少行为一致、无隐式转换陷阱。
- 原始值(
string、number、boolean)在Set中按值去重 -
NaN和NaN被视为相等(数组的indexOf(NaN)却找不到) - 对象、函数只按引用判断是否重复,不是深比较
Set 的基础操作:增删查遍历
它不像数组有下标,所有操作都通过方法调用完成,且返回值设计统一:add 和 delete 返回 Set 本身(可链式),has 返回布尔值,size 是只读属性。
立即学习“Java免费学习笔记(深入)”;
- 添加:
set.add(42)、set.add("hello"),重复值不报错,也不生效 - 检查存在:
set.has(42)—— 注意不是in操作符(那是为对象属性设计的) - 删除:
set.delete("hello"),返回true表示删除成功,false表示不存在 - 清空:
set.clear(),无返回值 - 遍历:
for (const item of set) { ... },或用set.forEach(cb),顺序是插入顺序
别误用 set[0] 或 set.length —— 它们都是 undefined。
每个应用程序都要使用数据,Android应用程序也不例外,Android使用开源的、与操作系统无关的SQL数据库--SQLite,本文介绍的就是如何为你的Android应用程序创建和操作SQLite数据库。 数据库支持每个应用程序无论大小的生命线,除非你的应用程序只处理简单的数据,那么就需要一个数据库系统存储你的结构化数据,Android使用SQLite数据库,它是一个开源的、支持多操作系统的SQL数据库,在许多领域广泛使用,如Mozilla FireFox就是使用SQLite来存储配置数据的,iPhon
把 Set 当工具用:去重、交集、差集
原生 Set 不直接提供交/并/差方法,但组合扩展运算符和数组方法就能写得又短又清楚,无需引入 Lodash。
- 数组去重:
[...new Set([1,2,2,3])] → [1,2,3] - 两 Set 交集:
new Set([...setA].filter(x => setB.has(x))) - setA 对 setB 的差集(A 有但 B 没有):
new Set([...setA].filter(x => !setB.has(x))) - 转为数组再映射:
[...set].map(x => x * 2),比Array.from(set, x => x * 2)更直观
注意:这些操作都会新建 Set 或数组,原 Set 不变;如果数据量大,避免在循环里反复展开 [...set],先缓存。
Set 和 Map、WeakSet 的关键区别
选错类型会导致内存泄漏或功能受限。比如想存 DOM 元素并随元素销毁自动清理,必须用 WeakSet(只接受对象,且不阻止 GC);而 Set 会强引用对象,可能导致内存堆积。
-
Map存键值对,键可以是任意类型(包括对象),Set只存值,没有键的概念 -
WeakSet不能遍历、没有size、不支持clear,仅提供add/delete/has -
Set的值可为任意类型,但NaN和0、-0的处理与严格相等(===)一致:0 === -0为true,所以它们在Set中算同一个值
真正容易被忽略的一点:你无法序列化 Set 为 JSON —— JSON.stringify(new Set([1,2])) 得到 "{}",必须先转成数组。










