Set去重快于filter+indexOf,因其基于哈希表实现平均O(1)查找,而indexOf每次遍历导致O(n²);Set还正确处理NaN、保持顺序且语义更可靠。

Set 在大型数据去重时比 filter + indexOf 快,核心在于查重机制不同:Set 用哈希表实现平均 O(1) 查找,而 indexOf 每次都要从头遍历数组,导致整体 O(n²)。
查重方式决定时间复杂度差异
Set 底层是哈希表结构。往 Set 中添加一个值时,它通过哈希计算快速判断该值是否已存在,平均只需一次操作(O(1))。遍历百万个元素,总开销就是约一百万次操作。
indexOf 则完全不同:对数组中每个元素,都得调用 arr.indexOf(item),而这个方法会从索引 0 开始逐个比对,直到找到或遍历完。外层循环 n 次,内层平均也执行 n/2 次,总操作量接近 n²/2 —— 百万级数据下就是约 5000 亿次比较。
- Set:O(n),100 万数据 ≈ 10⁶ 次操作
- filter + indexOf:O(n²),100 万数据 ≈ 10¹² 次操作
实际性能差距有多明显
在真实测试中,对 10 万条随机重复数据:
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
立即学习“Java免费学习笔记(深入)”;
- Set 方案通常耗时 几十毫秒
- filter + indexOf 方案普遍需要 几秒甚至更久
数据量翻倍时,Set 耗时基本线性增长;而 indexOf 方案的耗时会呈平方级飙升,浏览器容易卡顿或触发长任务警告。
Set 还额外解决了几个隐性问题
除了快,Set 在语义和边界处理上也更可靠:
- 能正确识别
NaN:Set 认为两个 NaN 相等,indexOf却因NaN !== NaN总是返回 -1,导致 NaN 被重复保留 - 使用 SameValueZero 算法比较,与
===行为一致(除 NaN 外),逻辑更符合直觉 - 天然保持首次出现顺序,无需额外维护索引逻辑
注意它的适用边界
Set 高效的前提是处理基本类型(数字、字符串、布尔值等):
- 对对象、数组等引用类型,Set 比较的是内存地址,不是内容。两个字段完全相同的对象仍被视为不同元素
- 若需对象去重,应改用 Map(按某字段作 key)或手动序列化+Set,但要注意性能与精度取舍
- IE11 及更早版本不支持 Set,如需兼容旧环境,得降级方案


















