跳转到主内容
趣航编程网 - 趣学编程,启航技术之路!

如何通过entrySet获取键值对对象并提升Map遍历效率

entrySet() 返回 Set>,比 keySet()+get() 快因避免重复哈希查找;遍历时 setValue() 在 HashMap 中安全但 TreeMap 不支持;Stream 操作更简洁高效;删除须用 Iterator.remove() 或 removeIf()。 entrySet() 返回的是什么类型,为什么比 keySet() + get() 快
entrySet()
返回的是
Set>
,每个元素是封装了键和值的
Map.Entry
对象。它避免了在遍历时反复调用
get()
查找值——而
keySet()
配合
map.get(key)
每次都要走哈希计算+桶查找,尤其在大 Map 或自定义 key 的场景下开销明显。 常见错误是写成这样:
for (String key : map.keySet()) { String value = map.get(key); // 多余的哈希查找 }
正确做法直接解构
Map.Entry
:
for (Map.Entry entry : map.entrySet()) { String key = entry.getKey(); Integer value = entry.getValue(); }
增强 for 循环里修改 value 是否安全 对
Map.Entry
调用
setValue()
是允许的,且会同步更新原 Map 中对应键的值(前提是 Map 实现支持,如
HashMap
、
LinkedHashMap
)。 但要注意以下几点:
TreeMap
的
entrySet()
迭代器不支持
setValue()
,会抛
UnsupportedOperationException
不能通过
entry.setValue()
修改 key 的内容(比如改
String
内容),否则破坏哈希一致性,后续
get()
可能失效 遍历中调用
map.remove(key)
或
iterator.remove()
是安全的;但直接调用
map.put()
可能触发 fail-fast Stream API 中用 entrySet() 做过滤或转换更简洁 相比先取 key 再
get()
,用
entrySet().stream()
直接操作键值对语义更清晰、性能更好。 例如筛选 value > 10 的条目并转成新 Map:
Map filtered = map.entrySet().stream() .filter(entry -> entry.getValue() > 10) .collect(Collectors.toMap( Map.Entry::getKey, Map.Entry::getValue ));
注意点: 如果 value 可能为 null,
entry.getValue() > 10
会 NPE,需先判空
Collectors.toMap()
在 key 冲突时默认抛
IllegalStateException
,必要时传第三个合并函数 对超大 Map,考虑用
parallelStream()
,但要注意线程安全和装箱开销 迭代过程中删除元素必须用 Iterator.remove() 直接在增强 for 中调用
map.remove(key)
会导致
ConcurrentModificationException
,因为
entrySet()
迭代器检测到结构修改。 安全删除方式只有两种: 用显式
Iterator
并调用其
remove()
方法 用
removeIf()
(JDK 8+),它内部封装了安全删除逻辑 示例:
Iterator> iter = map.entrySet().iterator(); while (iter.hasNext()) { Map.Entry entry = iter.next(); if (entry.getValue() < 0) { iter.remove(); // ✅ 安全 } }
或者更简洁:
map.entrySet().removeIf(entry -> entry.getValue() < 0);
别小看这个细节:线上高频遍历删元素的代码,漏掉这一步就容易崩。

相关文章