keyset()返回键的实时set视图,支持删除但不支持添加;values()返回值的实时collection视图,支持删除但不保证顺序或唯一性;二者均为map的活视图,修改会同步影响原map,需注意并发安全及副本创建。

Java 中的 Map 接口提供了 keySet() 和 values() 两个方法,分别用于获取所有键的集合和所有值的集合。它们返回的是视图(view),即底层与原 Map 关联,修改视图可能影响原 Map(取决于具体实现和操作)。
使用 keySet() 提取所有键
keySet() 返回一个 Set<k></k>,包含 Map 中所有键。这个 Set 是 Map 的“实时视图”——不支持添加元素,但可以通过它删除键(同时删除对应键值对)。
- 直接遍历键:用增强 for 循环或迭代器
- 转成数组或 List:如
new ArrayList(map.keySet()) - 注意:不能通过该 Set 添加新键(会抛
UnsupportedOperationException)
示例:
Mapmap.put("a", 1); map.put("b", 2);
Set
for (String key : keys) {
System.out.println(key); // 输出 a、b
}
使用 values() 提取所有值
values() 返回一个 Collection<v></v>,包含 Map 中所有值。它也是视图,允许删除(会同步删除对应键值对),但不保证顺序或唯一性(值可重复)。
- 适合只关心值内容的场景,比如统计、查找最大值等
- 不能通过该 Collection 添加值;调用
remove()会从原 Map 中移除对应条目 - 若需排序或去重,建议先转为 List 或 Set 再处理
示例:
Collectionint max = Collections.max(vals); // 得到 2
List
常见误区与注意事项
这两个方法返回的都不是独立副本,而是 Map 的“活视图”。这意味着:
- 后续对 Map 的增删改,会反映在 keySet/values 视图中(反之亦然,仅限删除)
- 并发修改(多线程)可能导致
ConcurrentModificationException,除非使用线程安全的 Map 实现(如ConcurrentHashMap) - 若需要真正独立的副本,应显式构造新容器:
new HashSet(map.keySet())或new ArrayList(map.values())
对比 entrySet() 的适用场景
如果既要键又要值,优先用 entrySet(),比分别遍历 keySet + get(key) 更高效(避免哈希查找)。
-
keySet():只处理键,比如检查某个权限是否存在 -
values():只处理值,比如找出所有大于 100 的分数 -
entrySet():需键值配对操作,比如打印完整映射关系
不复杂但容易忽略细节。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











