用 set 实现交集比遍历数组快得多,核心是利用 set 的 o(1) 查找性能,避免嵌套循环的 o(n×m) 时间开销;基础写法为 filter + has,优化版先转较小 set 为数组再过滤,手动遍历版更省内存。

用 Set 实现交集比遍历数组快得多,核心是利用 Set 的 O(1) 查找性能,避免嵌套循环的 O(n×m) 时间开销。
基础写法:用 filter + has
这是最直观、兼容性好、代码简洁的方式:
function intersection(setA, setB) {
return new Set([...setA].filter(x => setB.has(x)));
}
// 示例
const a = new Set([1, 2, 3, 4]);
const b = new Set([3, 4, 5, 6]);
console.log([...intersection(a, b)]); // [3, 4]
- 先将较小的 Set 转为数组(优化性能),再对它调用
filter -
setB.has(x)是常数时间查找,整体复杂度降为 O(n)(n 是较小 Set 的大小) - 返回新 Set,自动去重,适合后续继续 Set 操作
更省内存:手动遍历 + add
避免展开整个 Set 成数组,适合处理大集合:
function intersection(setA, setB) {
const result = new Set();
const [smaller, larger] = setA.size
- 显式比较大小,始终遍历较小的 Set,减少循环次数
- 不创建中间数组,内存占用更低
- 适用于 Set 元素较多(如上万项)或内存敏感场景
扩展支持多个 Set 的交集
把交集逻辑泛化为可接受任意数量 Set 的工具函数:
function intersection(...sets) {
if (sets.length === 0) return new Set();
if (sets.length === 1) return new Set(sets[0]);
const [first, ...rest] = sets;
let result = new Set(first);
for (const set of rest) {
const next = new Set();
for (const item of result) {
if (set.has(item)) next.add(item);
}
result = next;
}
return result;
}
// 示例
const s1 = new Set([1, 2, 3]);
const s2 = new Set([2, 3, 4]);
const s3 = new Set([3, 4, 5]);
console.log([...intersection(s1, s2, s3)]); // [3]
- 逐个缩小交集结果:用第一个 Set 初始化,再依次与后续每个 Set 取交
- 每次迭代都新建临时 Set,保证不可变性,也避免修改原始数据
- 仍保持“只遍历当前 result”的策略,效率随交集缩小而提升
注意边界与类型细节
Set 交集看似简单,但实际使用中容易踩坑:
-
NaN 和 -0 的特殊性:Set 中
NaN === NaN为 false,但 Set 视为相同值;-0和+0在 Set 中也被视为相等 - 引用类型需谨慎:对象、数组等引用值只有完全同一引用才被识别为“相同”,不是结构相等。如需结构交集,得先序列化或自定义比较逻辑
-
空 Set 或无交集时返回空 Set,不是
null或undefined,直接解构或遍历即可,无需额外判空
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











