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