set对引用类型只按内存地址判重而非内容,故相同结构的对象或数组视为不同元素;nan和±0是例外,被统一视为相等;内容去重需手动映射为原始值或使用json.stringify等策略。

Set 对引用类型不做内容比较,只认内存地址。
引用类型去重靠的是“引用相等”,不是“内容相等”
Set 判断两个值是否重复,用的是严格相等(===)。对对象、数组、函数这类引用类型来说,=== 比较的是它们在内存中的地址,而不是结构或字段是否一样。
- 哪怕两个对象长的一模一样:
{id: 1, name: 'Alice'}和{id: 1, name: 'Alice'},只要不是同一个对象实例,Set 就当它们是不同的元素 - 同一个对象多次添加,Set 只保留一份:
const obj = {x: 1}; new Set([obj, obj])→ 长度为 1 - 数组也一样:
new Set([[1], [1]])会保留两个子数组,因为它们是不同引用
想按内容去重,得自己加一层唯一标识逻辑
Set 本身不提供深比较能力,但你可以绕过它,提前把引用类型映射成可比的原始值。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 有明确 id 字段时,用
Map或Set存 id:const seen = new Set(); arr.filter(item => !seen.has(item.id) && seen.add(item.id)) - 结构简单且可序列化时,可用
JSON.stringify生成唯一键:const seen = new Set(); arr.filter(item => !seen.has(JSON.stringify(item)) && seen.add(JSON.stringify(item))) - 注意:JSON.stringify 不能处理函数、undefined、Symbol、循环引用,也不区分
1和"1",慎用于复杂对象
NaN 和 +0/-0 是例外,Set 内部做了特殊处理
虽然 NaN !== NaN,但 Set 把所有 NaN 当作同一个值;+0 和 -0 在 Set 中也被视为相等。这是 Set 的内置行为,和引用类型无关,但值得留意。
-
new Set([NaN, NaN])→ 只有一个 NaN -
new Set([+0, -0])→ 只有一个 0 - 这种一致性仅限于这些特殊值,不扩展到对象或数组
Set 的设计本意就是轻量、高效、基于引用判重。需要内容级去重时,它不替代逻辑判断,而是配合你已有策略一起用。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










