Map 与 Collection 是 Java 集合框架中并列的顶层接口,无继承关系;Map 存储键值对且 key 唯一,不实现 Iterable,故不能直接用增强 for 循环遍历;其 keySet() 返回 Set,values() 返回 Collection(因 value 可重复),entrySet() 返回 Set;Collections 工具类方法不适用于 Map,需用 ConcurrentHashMap 或 Collections.synchronizedMap() 等专用方式实现线程安全。

Map 和 Collection 根本不是同一类东西
Java 中 Map 接口和 Collection 接口**没有继承关系**,也不是“子集 vs 父集”——它们是集合框架里并列的两个顶层接口。很多人误以为 Map 是 Collection 的一种,结果在写 for (Object obj : map) 时直接编译报错:Foreach not applicable to type 'java.util.Map'。这是因为 Map 不实现 Iterable,没法直接用增强 for 循环遍历整个 Map 对象。
Collection 存的是单个对象,Map 存的是键值对
这是最本质的行为差异:
-
Collection(比如ArrayList、HashSet)只管“装东西”,每个位置存一个独立对象; -
Map(比如HashMap)必须成对存:key和value缺一不可,且key必须唯一(重复 put 同 key 会覆盖旧 value)。
所以你不能把 Map 当作“能放任意对象的容器”来用。想取数据?得明确你是要 keySet()、values() 还是 entrySet() —— 它们返回的分别是 Set、Collection、Set,类型和用途都不同。
为什么 values() 返回 Collection 而不是 Set?
因为 value 允许重复,key 才强制唯一。所以:
立即学习“Java免费学习笔记(深入)”;
-
map.keySet()→ 返回Set:天然去重,符合 key 唯一性约束; -
map.values()→ 返回Collection(通常是Collection实现,非 Set):不保证去重,也不该去重; -
map.entrySet()→ 返回Set:Entry 本身由 key 唯一决定,所以整个 Entry 集合也唯一。
常见误操作:new HashSet(map.values()) 想去重 value —— 这没问题,但别误以为 values() 本来就是 Set。
别拿 Collection 工具类硬套 Map
Collections 工具类(注意首字母大写)的方法,如 Collections.sort()、Collections.synchronizedList(),全部只接受 Collection 及其子类参数。它对 Map 完全无效。
想让 Map 线程安全?不能写 Collections.synchronizedCollection(map) —— 编译不过。正确做法是:
- 用
ConcurrentHashMap(推荐); - 或用
Collections.synchronizedMap(new HashMap())(注意方法名是synchronizedMap,不是synchronizedCollection); - 或者包装成不可变视图:
Collections.unmodifiableMap(map)。
最容易被忽略的一点:Map 的“结构”只由 key 决定,value 完全不影响哈希分布、排序顺序或去重逻辑。哪怕两个 value 完全一样,只要 key 不同,它们就是两个独立映射项——这点和 Set 的“元素即判重依据”有根本区别。










