map本身不提供按键去重操作,因其键天然唯一、重复设值自动覆盖;按属性(如id)去重本质是用该属性作key构建map实现归一化缓存,保留最后或首次出现项需分别直接set或配合has判断;非基本类型键需序列化后比较内容。

Map 本身不提供“按键去重”的操作,因为它的设计就是:每个键唯一,重复设值会自动覆盖。所以如果你有多个对象或数据,想“按某个属性(如 id)作为键来去重”,本质是**用 Map 做归一化缓存**——把目标属性作为 key,把整个对象(或需要保留的数据)作为 value。
用对象的某个字段作 key 构建 Map 实现去重
这是最常见场景:比如有一组用户数据,要按 id 去重,保留最后出现的那条:
const users = [
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' },
{ id: 1, name: 'Alice Updated' }, // 重复 id
{ id: 3, name: 'Charlie' }
];
// 按 id 去重:后出现的覆盖先出现的
const uniqueMap = new Map();
users.forEach(user => uniqueMap.set(user.id, user));
// 转回数组(去重后)
const uniqueUsers = Array.from(uniqueMap.values());
// → [{ id: 1, name: 'Alice Updated' }, { id: 2, name: 'Bob' }, { id: 3, name: 'Charlie' }]
如果想保留首次出现的,而不是最后的
只需判断 key 是否已存在,只在不存在时设置:
- 用
map.has(key)判断 - 只在
!map.has(key)时调用set()
const uniqueMap = new Map();
users.forEach(user => {
if (!uniqueMap.has(user.id)) {
uniqueMap.set(user.id, user);
}
});
处理非基本类型键(如对象、数组)需注意
Map 的键支持任意类型,但对象/数组作键时,不是按内容比较,而是按引用:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
-
map.set({a:1}, 'x')和map.set({a:1}, 'y')是两个不同键(因为是两个不同对象) - 若真要“按内容去重”,得先序列化(如
JSON.stringify),或用第三方库(如 Lodash 的isEqual)做归一化
例如按对象内容去重(简单场景,无嵌套/函数/undefined):
const items = [{a:1}, {b:2}, {a:1}];
const mapByContent = new Map();
items.forEach(obj => {
const key = JSON.stringify(obj);
if (!mapByContent.has(key)) {
mapByContent.set(key, obj);
}
});
const uniqueByContent = Array.from(mapByContent.values());
配合其他结构快速提取去重结果
除了 Array.from(map.values()),你也可以:
- 取所有键:
Array.from(map.keys()) - 取键值对数组:
Array.from(map.entries()) - 直接遍历:
for (const [key, value] of map) { ... }
Map 的插入顺序天然保持,所以转成数组后顺序和最后一次 set 的顺序一致。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










