Java Map 的 entrySet() 方法详解及用法,一篇就够了!
引言
在 Java 集合框架中,Map接口的entrySet()方法是最常用且最高效的遍历方式之一。它返回 Map 中所有键值对映射关系的集合视图(Set<Map.Entry<K, V>>),通过这个视图我们可以同时访问 key 和 value,甚至在遍历过程中修改 Map 的内容。
相比keySet()(只能取 key 再 get value)和values()(只能取 value),entrySet()在需要同时操作键和值时性能更好,因为避免了重复的 key 查找操作。
掌握entrySet(),能让你写出更优雅、更高效的 Map 遍历代码!
entrySet() 方法签名与返回值
publicSet<Map.Entry<K,V>>entrySet()- 返回值:一个包含 Map 中所有映射关系的
Set视图。 - 每个元素是
Map.Entry<K, V>类型对象,代表一个键值对。 - 该 Set 是 Map 的后台视图(backing view):对 Set 的修改会反映到原 Map,反之亦然。
- 不支持添加新元素(会抛 UnsupportedOperationException),但支持 remove 和 clear。
Map.Entry 接口核心方法
interfaceMap.Entry<K,V>{KgetKey();// 获取键VgetValue();// 获取值VsetValue(Vvalue);// 修改值(会同步修改原 Map)booleanequals(Objecto);inthashCode();}重点:setValue()可以直接修改 Map 中的值!
常见用法详解
用法1:增强 for 循环遍历(最常用)
Map<String,Integer>map=newHashMap<>();map.put("Apple",10);map.put("Banana",20);map.put("Orange",15);for(Map.Entry<String,Integer>entry:map.entrySet()){Stringkey=entry.getKey();Integervalue=entry.getValue();System.out.println(key+" = "+value);}输出:
Apple = 10 Banana = 20 Orange = 15优势:代码清晰,性能最佳(推荐!)
用法2:Iterator 显式迭代器(可安全删除元素)
Iterator<Map.Entry<String,Integer>>iterator=map.entrySet().iterator();while(iterator.hasNext()){Map.Entry<String,Integer>entry=iterator.next();if(entry.getValue()<18){iterator.remove();// 安全删除}}关键:删除时必须用iterator.remove(),不能用map.remove(key)(会抛 ConcurrentModificationException)。
用法3:在遍历中修改值
for(Map.Entry<String,Integer>entry:map.entrySet()){// 将所有值翻倍entry.setValue(entry.getValue()*2);}System.out.println(map);// {Apple=20, Banana=40, Orange=30}这是entrySet()的独有能力!用 keySet() 做不到这么简洁。
用法4:结合 Java 8 Lambda 表达式(现代写法)
// 遍历打印map.entrySet().forEach(entry->System.out.println(entry.getKey()+" -> "+entry.getValue()));// 修改值map.entrySet().forEach(entry->entry.setValue(entry.getValue()+100));// 过滤并收集新 MapMap<String,Integer>filtered=map.entrySet().stream().filter(entry->entry.getValue()>15).collect(Collectors.toMap(Map.Entry::getKey,Map.Entry::getValue));用法5:排序 Map(经典应用)
List<Map.Entry<String,Integer>>list=newArrayList<>(map.entrySet());list.sort(Map.Entry.comparingByValue(Comparator.reverseOrder()));// 按值降序// 前3名for(inti=0;i<Math.min(3,list.size());i++){System.out.println(list.get(i).getKey()+": "+list.get(i).getValue());}三种遍历方式性能对比
| 方式 | 代码复杂度 | 性能(大 Map 时) | 可修改值 | 可安全删除 |
|---|---|---|---|---|
| entrySet() | 低 | 最快 | 是 | 是 |
| keySet() + get(key) | 中 | 慢(重复查找) | 是 | 是(慎用) |
| values() | 高 | 快 | 否 | 否 |
结论:能用entrySet()就优先用!
注意事项与常见坑
entrySet()返回的是视图,不是副本。修改视图 = 修改原 Map。- 某些 Map 实现(如 ConcurrentHashMap)在迭代时若结构发生变化仍可能抛异常,建议使用 Iterator。
- 不支持向 entrySet 添加新元素:
map.entrySet().add(newAbstractMap.SimpleEntry<>("new",1));// 抛 UnsupportedOperationException - 在多线程环境下,建议使用 ConcurrentHashMap 或外部同步。
总结:什么时候用 entrySet()
- 需要同时访问 key 和 value → 首选 entrySet()
- 需要在遍历中修改值 → 必须用 entrySet()
- 需要删除元素 → 用 entrySet() + Iterator
- 需要排序或流式处理 → entrySet() 是最佳起点
掌握了entrySet(),你就掌握了 Java Map 遍历的精髓!下次处理 Map 时,优先写:
for(Map.Entry<K,V>entry:map.entrySet()){...}代码更简洁,性能更优秀!建议收藏本文,反复实践这几种用法,轻松进阶 Java 集合高手!