entrySet()遍历比keySet()+get()更快,因其避免重复哈希计算或树查找,直接访问已有键值对引用;推荐增强for循环+Map.Entry,支持setValue()原地修改(ConcurrentHashMap除外)。

直接遍历 entrySet() 是 Java 中获取 Map 键值对最高效的方式,避免了通过 key 查 value 的重复哈希计算或树查找开销。
为什么 entrySet() 比 keySet() + get() 更快
使用 keySet() 遍历再调用 get() 会触发额外的查找操作:HashMap 需要重新计算 hash、定位桶、处理冲突;TreeMap 则需从根节点开始查找。而 entrySet() 返回的是已存在的键值对引用,遍历时直接访问,无额外查找成本。
推荐写法:增强 for 循环 + Map.Entry
这是最简洁且性能最优的常用方式:
for (Map.Entry<String, Integer> entry : map.entrySet()) {
String key = entry.getKey();
Integer value = entry.getValue();
// 处理逻辑
}
- 适用于所有 Map 实现(HashMap、LinkedHashMap、ConcurrentHashMap 等)
- JVM 对这种遍历做了良好优化,字节码简洁
- 避免创建中间 key 数组或 iterator 包装对象(相比老式 while + iterator)
需要修改 value 时:用 Entry 的 setValue()
某些 Map(如 HashMap)的 Entry 支持 setValue(),可原地更新,比先 remove() 再 put() 更高效:
立即学习“Java免费学习笔记(深入)”;
for (Map.Entry<String, Integer> entry : map.entrySet()) {
if (entry.getValue() < 0) {
entry.setValue(0); // 直接修改,不触发 rehash 或结构变更
}
}
- 注意:ConcurrentHashMap 的 entry 不支持
setValue()(抛UnsupportedOperationException) - 修改后是否可见取决于 Map 实现的线程安全性,非并发场景下安全
大量数据或需并行处理时考虑 Stream(谨慎评估)
Java 8+ 可用 map.entrySet().stream(),但默认是顺序流,且有对象包装开销:
map.entrySet().stream() .filter(e -> e.getValue() > 100) .forEach(e -> System.out.println(e.getKey()));
- 仅当已有 Stream 流水线、或需复杂转换/过滤时才用,纯遍历不推荐
- 如需并行,可用
parallelStream(),但要注意线程安全和小集合反而更慢 - 避免在 lambda 中频繁装箱/拆箱(如用
Integer::intValue替代e.getValue()做数值计算)
不复杂但容易忽略:始终优先用 entrySet() 遍历,除非你只用 key 或只用 value。



















