entrySet()遍历键值对最常用且推荐,避免重复查表;仅需key或value时选keySet()或values();遍历时删除须用Iterator.remove();多线程优先用ConcurrentHashMap。

用 entrySet() 遍历键值对最常用也最推荐
绝大多数场景下,要同时访问 key 和 value,entrySet() 是最优选择。它返回的是 Set,每个 Map.Entry 封装了一组键值对,避免了重复查表开销。
常见错误是先用 keySet() 获取 key,再循环调用 map.get(key) —— 对 HashMap 影响不大,但对 TreeMap 或自定义 Map 实现可能触发多次查找或排序逻辑,性能打折。
实操建议:
- 用增强 for 循环直接遍历
entrySet(),简洁安全 - 若需修改 value,可调用
entry.setValue(newVal)(仅对支持修改的 Map 有效) - 不要在遍历时直接调用
map.remove(key),会抛ConcurrentModificationException;应使用Iterator.remove()
for (Map.Entryentry : map.entrySet()) { String key = entry.getKey(); Integer value = entry.getValue(); System.out.println(key + "=" + value); }
只遍历 key 或只遍历 value 时选 keySet() 或 values()
如果业务逻辑只需要 key(比如判断是否存在某 key、批量做 key 格式校验),用 keySet();如果只关心 value(比如统计所有 value 的总和、找最大值),用 values()。两者都比 entrySet() 少一层封装,内存和 CPU 开销略小。
立即学习“Java免费学习笔记(深入)”;
注意点:
-
values()返回的是Collection,不保证顺序(除非底层 Map 有序,如LinkedHashMap或TreeMap) -
keySet()和values()返回的集合是 Map 的“视图”,修改它们会直接影响原 Map(例如调用keySet().remove("k1")等价于map.remove("k1")) - 不能通过
values()反查 key —— 没有映射关系保障,多个 key 可能对应相同 value
需要并发安全或边遍历边删除时必须用 Iterator
当遍历过程中要删除元素,或 Map 被多线程共享(哪怕只是读多写少),就不能依赖增强 for 循环——它底层隐式使用 Iterator,但没暴露 remove 方法,且无法应对并发修改。
正确做法是显式获取 Iterator,并在循环中调用其 remove() 方法:
Iterator> iter = map.entrySet().iterator(); while (iter.hasNext()) { Map.Entry entry = iter.next(); if (entry.getValue() < 0) { iter.remove(); // 安全删除 } }
其他注意事项:
- 对
ConcurrentHashMap,可放心用增强 for 遍历(不会抛ConcurrentModificationException),但删除仍需用computeIfPresent()或remove()方法,不能依赖Iterator.remove() - 若在多线程环境下仅读取,优先用
ConcurrentHashMap替代synchronized(new HashMap())
Lambda 方式(Java 8+)适合简单过滤或转换,别滥用
forEach() 和 stream() 写法看起来更函数式,但实际有隐含成本和限制:
-
map.forEach((k, v) -> {...})底层仍是entrySet()+ 增强 for,语法糖而已,不提升性能 -
map.entrySet().stream()...会额外创建 Stream 对象和中间操作链,小数据量无感,大数据量或高频调用时 GC 压力明显 - lambda 表达式里无法
break或continue,想提前退出只能抛异常(不推荐)或改用传统循环 - Stream 并行化(
parallelStream())对 Map 遍历收益极低,还可能因 key 分布不均导致负载不均
真正适合用 lambda 的场景:一次性的、带过滤/映射/聚合的简单操作,比如 map.values().stream().filter(Objects::nonNull).mapToInt(Integer::intValue).sum()。









