Map 与 Collection 是 Java 集合框架中并列的顶层接口,无继承关系;Map 存储键值对且 key 唯一,不实现 Iterable,故不能直接用增强 for 循环遍历;其 keySet() 返回 Set,values() 返回 Collection(因 value 可重复),entrySet() 返回 Set;Collections 工具类方法不适用于 Map,需用 ConcurrentHashMap 或 Collections.synchronizedMap() 等专用方式实现线程安全。
Java 中 Map 接口和 Collection 接口**没有继承关系**,也不是“子集 vs 父集”——它们是集合框架里并列的两个顶层接口。很多人误以为 Map 是 Collection 的一种,结果在写 for (Object obj : map) 时直接编译报错:Foreach not applicable to type 'java.util.Map'。这是因为 Map 不实现 Iterable,没法直接用增强 for 循环遍历整个 Map 对象。
这是最本质的行为差异:
Collection(比如 ArrayList、HashSet)只管“装东西”,每个位置存一个独立对象;Map(比如 HashMap)必
key 和 value 缺一不可,且 key 必须唯一(重复 put 同 key 会覆盖旧 value)。所以你不能把 Map 当作“能放任意对象的容器”来用。想取数据?得明确你是要 keySet()、values() 还是 entrySet() —— 它们返回的分别是 Set、Collection、Set,类型和用途都不同。
因为 value 允许重复,key 才强制唯一。所以:
map.keySet() → 返回 Set:天然去重,符合 key 唯一性约束;map.values() → 返回 Collection(通常是 Collection 实现,非 Set):不保证去重,也不该去重;map.entrySet() → 返回 Set:Entry 本身由 key 唯一决定,所以整个 Entry 集合也唯一。常见误操作:new HashSet(map.values()) 想去重 value —— 这没问题,但别误以为 values() 本来就是 Set。
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 的“元素即判重依据”有根本区别。