HashMap的遍历

要介绍HashMap的四种循环遍历方式,各种方式的性能测试对比,根据HashMap的源码实现分析性能结果,总结结论。



1. Map的四种遍历方式
下面只是简单介绍各种遍历示例(以HashMap为例),各自优劣会在本文后面进行分析给出结论。

(1) for each map.entrySet()




Java
Map<String, String> map = new HashMap<String, String>();
for (Entry<String, String> entry : map.entrySet()) {
entry.getKey();
entry.getValue();
}


1

2

3

4

5
Map<String, String> map = new HashMap<String, String>();
for (Entry<String, String> entry : map.entrySet()) {
entry.getKey();
entry.getValue();
}





(2) 显示调用map.entrySet()的集合迭代器




Java
Iterator<Map.Entry<String, String>> iterator = map.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, String> entry = iterator.next();
entry.getKey();
entry.getValue();
}


1

2

3

4

5

6
Iterator<Map.Entry<String, String>> iterator = map.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, String> entry = iterator.next();
entry.getKey();
entry.getValue();
}





(3) for each map.keySet(),再调用get获取




Java
Map<String, String> map = new HashMap<String, String>();
for (String key : map.keySet()) {
map.get(key);
}


1

2

3

4
Map<String, String> map = new HashMap<String, String>();
for (String key : map.keySet()) {
map.get(key);
}





(4) for each map.entrySet(),用临时变量保存map.entrySet()




Java
Set<Entry<String, String>> entrySet = map.entrySet();
for (Entry<String, String> entry : entrySet) {
entry.getKey();
entry.getValue();
}


1

2

3

4

5
Set<Entry<String, String>> entrySet = map.entrySet();
for (Entry<String, String> entry : entrySet) {
entry.getKey();
entry.getValue();
}



在测试前大家可以根据对HashMap的了解,想想上面四种遍历方式哪个性能更优。



2、HashMap四种遍历方式的性能测试及对比
以下是性能测试代码,会输出不同数量级大小的HashMap各种遍历方式所花费的时间。


HashMap循环遍历方式性能对比测试代码


PS:如果运行报异常in thread “main” java.lang.OutOfMemoryError: Java heap space,请将main函数里面map size的大小减小。

其中getHashMaps函数会返回不同size的HashMap。
loopMapCompare函数会分别用上面的遍历方式1-4去遍历每一个map数组(包含不同大小HashMap)中的HashMap。
print开头函数为输出辅助函数,可忽略。



测试环境为Windows7 32位系统 3.2G双核CPU 4G内存,Java 7,Eclipse -Xms512m -Xmx512m
最终测试结果如下:




Java
compare loop performance of HashMap
-----------------------------------------------------------------------
map size | 10,000 | 100,000 | 1,000,000 | 2,000,000
-----------------------------------------------------------------------
for each entrySet | 2 ms | 6 ms | 36 ms | 91 ms
-----------------------------------------------------------------------
for iterator entrySet | 0 ms | 4 ms | 35 ms | 89 ms
-----------------------------------------------------------------------
for each keySet | 1 ms | 6 ms | 48 ms | 126 ms
-----------------------------------------------------------------------
for entrySet=entrySet()| 1 ms | 4 ms | 35 ms | 92 ms
-----------------------------------------------------------------------


1

2

3

4

5

6

7

8

9

10

11

12
compare loop performance of HashMap
-----------------------------------------------------------------------
map size | 10,000 | 100,000 | 1,000,000 | 2,000,000
-----------------------------------------------------------------------
for each entrySet | 2 ms | 6 ms | 36 ms | 91 ms
-----------------------------------------------------------------------
for iterator entrySet | 0 ms | 4 ms | 35 ms | 89 ms
-----------------------------------------------------------------------
for each keySet | 1 ms | 6 ms | 48 ms | 126 ms
-----------------------------------------------------------------------
for entrySet=entrySet()| 1 ms | 4 ms | 35 ms | 92 ms
-----------------------------------------------------------------------



表横向为同一遍历方式不同大小HashMap遍历的时间消耗,纵向为同一HashMap不同遍历方式遍历的时间消耗。
PS:由于首次遍历HashMap会稍微多耗时一点,for each的结果稍微有点偏差,将测试代码中的几个Type顺序调换会发现,for each entrySet耗时和for iterator entrySet接近。



3、遍历方式性能测试结果分析
(1) foreach介绍
见:ArrayList和LinkedList的几种循环遍历方式及性能对比分析中介绍。



(2) HashMap遍历方式结果分析
从上面知道for each与显示调用Iterator等价,上表的结果中可以看出除了第三种方式(for each map.keySet()),再调用get获取方式外,其他三种方式性能相当。本例还是hash值散列较好的情况,若散列算法较差,第三种方式会更加耗时。
我们看看HashMap entrySet和keySet的源码




Java
private final class KeyIterator extends HashIterator<K> {
public K next() {
return nextEntry().getKey();
}
}

private final class EntryIterator extends HashIterator<Map.Entry<K,V>> {
public Map.Entry<K,V> next() {
return nextEntry();
}
}


1

2

3

4

5

6

7

8

9

10

11
private final class KeyIterator extends HashIterator<K> {
public K next() {
return nextEntry().getKey();
}
}

private final class EntryIterator extends HashIterator<Map.Entry<K,V>> {
public Map.Entry<K,V> next() {
return nextEntry();
}
}



分别是keySet()和entrySet()返回的set的迭代器,从中我们可以看到只是返回值不同而已,父类相同,所以性能相差不多。只是第三种方式多了一步根据key get得到value的操作而已。get的时间复杂度根据hash算法而异,源码如下:




Java
public V get(Object key) {
if (key == null)
return getForNullKey();
Entry<K,V> entry = getEntry(key);

return null == entry ? null : entry.getValue();
}

/**
* Returns the entry associated with the specified key in the
* HashMap. Returns null if the HashMap contains no mapping
* for the key.
*/
final Entry<K,V> getEntry(Object key) {
int hash = (key == null) ? 0 : hash(key);
for (Entry<K,V> e = table[indexFor(hash, table.length)];
e != null;
e = e.next) {
Object k;
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
return e;
}
return null;
}


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25
public V get(Object key) {
if (key == null)
return getForNullKey();
Entry<K,V> entry = getEntry(key);

return null == entry ? null : entry.getValue();
}

/**
* Returns the entry associated with the specified key in the
* HashMap. Returns null if the HashMap contains no mapping
* for the key.
*/
final Entry<K,V> getEntry(Object key) {
int hash = (key == null) ? 0 : hash(key);
for (Entry<K,V> e = table[indexFor(hash, table.length)];
e != null;
e = e.next) {
Object k;
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
return e;
}
return null;
}



get的时间复杂度取决于for循环循环次数,即hash算法。



4、结论总结

从上面的分析来看:
a. HashMap的循环,如果既需要key也需要value,直接用




Java
Map<String, String> map = new HashMap<String, String>();
for (Entry<String, String> entry : map.entrySet()) {
entry.getKey();
entry.getValue();
}


1

2

3

4

5
Map<String, String> map = new HashMap<String, String>();
for (Entry<String, String> entry : map.entrySet()) {
entry.getKey();
entry.getValue();
}



即可,foreach简洁易懂。

b. 如果只是遍历key而无需value的话,可以直接用




Java
Map<String, String> map = new HashMap<String, String>();
for (String key : map.keySet()) {
// key process
}


1

2

3

4
Map<String, String> map = new HashMap<String, String>();
for (String key : map.keySet()) {
// key process
}
安卓开发者必看:Win11最新Fastboot驱动安装避坑指南(含Android Bootloader Interface选择技巧) 本文为安卓开发者提供了Windows 11系统下Fastboot驱动安装的详细指南,特别针对Android Bootloader Interface选择技巧和多设备并发连接时的驱动冲突问题。通过解析Windows 11的特殊驱动验证机制,推荐使用Google官方USB驱动,并提供安装流程、版本选择建议及疑难问题排查方法,帮助开发者高效完成开发环境配置。 阅读详情

相关推荐

Power BI应用案例:淘宝用户行为分析实战

一、案例背景 基于千万级的淘宝用户的使用记录,对淘宝用户的行为进行分析,具体指标包括:日PV、日UV、小时PV、小时UV、不同用户行为的PV、用户购买次数分布、用户购买频次分布、活跃用户消费情况等。通过本案例,可以基本看看Power BI都能分析达到怎么样的效果。 二、数据来源及结构 阿里天池官方发布的1万用户在2014年双十二期间的行为记录,数据量达1200万+。 数据下载地址:...

灰哥数据智能的专栏 1万+

HashMap循环遍历方式及其性能对比

为什么80%的码农都做不了架构师?>>> ...

weixin_34273481的博客 362

ResNet理论基础与具体实现(详细教程)

论文地址:Deep Residual Learning for Image Recognition ​ Identity Mappings in Deep Residual Networks pytroch源码地址:resnet 0x00 前言 ResNet是2015年就提出的网络结构,中文名字叫作深度残差网络,主要作用是图像分类。现在在图像分割、目标检测等领域都有很...

coordinate的博客 8331

HashMap循环遍历

HashMap的七种循环遍历方法 public class mapDemo { public static void main(String[] args) { // 创建并赋值HashMap Map<Integer, String> map = new HashMap<>(); map.put(1, "Java"); map.put(2, "C语言"); map.put(3, "php")

zhangfeiyue12178的博客 7945

别再踩坑了!手把手教你用EB Tresos Studio创建Autosar MCAL工程(含模块配置避坑指南)

本文详细介绍了使用EB Tresos Studio创建Autosar MCAL工程的完整流程,包括工程创建前的关键准备、模块配置的避坑指南以及工程验证与代码生成的实用技巧。通过实战案例和黄金准则,帮助开发者高效完成MCAL工程创建,避免常见错误,提升开发效率。

weixin_42536058的博客 444

软件工程导论考试通关秘籍:太原理工大学历年真题解析(附答案)

本文为太原理工大学《软件工程导论》考试提供高效备考指南,通过解析近六年真题,揭示高频考点如软件生命周期、UML建模和结构化设计等核心模块的命题规律。文章提供真题拆解、实战策略和避坑指南,帮助考生掌握图形转换题和简答题的应答技巧,助力考试通关。

weixin_29233333的博客 227

HashMap的四种遍历方式

第一种方式:采用for循环遍历key,然后根据key从HashMap中获取值 代码如下 @Test void mapTraversal1() { HashMap<String, String> map = new HashMap<>(); map.put("key1", "value1"); map.put("key2", "value2"); map.put("key3", "value3");

一位普普通通程序员的博客 7636

基于因果推理的LLM去毒:精准定位注意力头实现高效干预

在大型语言模型(LLM)的部署与应用中,模型安全与可控性是核心挑战之一。传统方法如全参数微调成本高昂,且可能损害模型通用能力。本文聚焦于一种基于因果推理的精准干预技术,其原理在于利用因果发现算法定位Transformer模型中与“毒性”输出存在强因果关联的特定注意力头。该技术通过分析注意力头的激活模式与生成文本毒性分数之间的因果关系,识别出关键责任单元,而非依赖传统的相关性分析。其技术价值在于实现了轻量级、高可解释性的模型行为修正,能以极低的参数改动代价有效降低模型在敏感话题上的有害输出。在应用场景上,该方

weixin_32667439的博客 313

【HashMap】遍历读和遍历删除

【5】方法五:stream流遍历以及lambda表达式遍历。【4】方法四:entrySet()迭代。【3】方法三:keySet()迭代。【一】遍历读HashMap。【1】方法一:for循环。【2】方法二:迭代器。

weixin_44823875的博客 1550

什么是 SAP ABAP AMDP?

SAP HANA是SAP开发的一种内存数据库管理系统,它具有出色的性能和处理大规模数据的能力。为了充分利用SAP HANA的性能,SAP引入了AMDP技术,以便将数据库操作推送到数据库服务器执行,从而减少数据传输和处理时间。AMDP方法通常需要输入参数和输出参数。输入参数用于传递数据到SQLScript代码,而输出参数用于接收SQLScript代码的结果数据。ENDMETHOD.ENDCLASS.我们定义了一个输入参数来传递销售订单数据,以及一个输出参数来接收计算结果。ENDMETHOD.

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 908

prplOS amx-fxgi调试-订阅subscribe

本文分析了prplOS中amx-fxgi订阅功能(subscribe)的实现与调试过程。通过梳理订阅流程发现,默认订阅失败主要由于acl规则限制导致。文章详细介绍了订阅的两个关键步骤:建立GET长连接和POST设置订阅路径,并通过修改代码绕过acl验证成功实现订阅功能。最终验证了在同一连接下订阅多个路径及实时接收状态更新的可行性,有效降低了设备查询负载。该方案为prplOS的实时数据监控提供了优化思路。

四儿家的小祖宗的博客 330

【Java】Java中使用HashMap优化多层for循环嵌套以及for循环之性能优化

for循环 里面还有 for循环, 然后做一些数据匹配、处理 这种场景。使用HashMap优化多级嵌套循环// 为stus写入10条数据 ... 略 List < Grade > gs = new ArrayList < >();// 为gs写入10条数据 ... 略 for(int i = 0;i ++) {j ++) {System . out . println("学生:" + stuName + ",成绩:" + g . getValue());} } } }

DreamSun的博客 2075

面试官连夜整理:103道AI Agent面试题,答对一半直接加薪50%

维度AutoGPTLangGraphAutoGen控制流LLM 驱动的隐式循环代码层定义的显式状态图对话驱动的自动流转状态存储Prompt 上下文中(易丢失)结构化 State 对象(可持久化)对话历史(自动累积)分支能力依赖 LLM 的文本输出(不稳定)条件边 + 节点路由(确定性)多 Agent 对话自然分支(涌现式)回溯/回滚无原生支持,只能重新开始原生 Checkpoint 支持时间旅行无全局回滚,单 Agent 可重启人机协同仅人工在关键点介入(需要自定义)原生支持。

weixin_35774598的博客 622

HashMap的遍历输出

import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Set; public class MapDemo { public static void main(String[] args) { Map<String, Integer> map = ...

weixin_44519263的博客 1430

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

如何遍历 HashMap,遍历HashMap 的 5 种最佳方式

在本文中,我们将通过示例讨论在 Java 上遍历 HashMap 的五种最佳方法。 使用 Iterator 遍历 HashMap EntrySet 使用 Iterator 遍历 HashMap KeySet 使用 For-each 循环迭代 HashMap 使用 Lambda 表达式遍历 HashMap 使用 Stream API 遍历 HashMap 1. 使用 Iterator 遍历 HashMap EntrySet packagecom.ja..

飞熊的博客 3235

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

遍历HashMap

第五周HashMap遍历方式1.增强型for遍历1.迭代器遍历 HashMap遍历方式 1.增强型for遍历 直接看代码: String dog1 = ("田园犬"); String dog2 = ("萨摩耶"); String dog3 = ("哈士奇"); Map map = new HashMap(); map.put("大黄", dog1); map.put("火腿", dog2); map.put("薯片", dog3);

leno_scholar的博客 343

遍历HashMap,有6种方式,你学会了没?

在 Java 中,有多种方式可以遍历 HashMap,下面为你详细介绍几种常见的遍历方法。

只讲干货,不扯淡! 2313

HashMap、创建并遍历HashMap集合、LinkedHashMap

HashMap是基于哈希表的Map实现。键是哈希表结构,可以保证键的唯一性。 HashMap 继承于AbstractMap,实现了Map接口。 HashMap的设计初衷主要是为了解决键值(key-value)对应的关联的,HashMap的优势是可以很快的根据键(key)找到该键对应的值(value)。注意一下,HashMap是一种无序的存储结构。 遍历 1.案例1 键String类型,值S...

元气满满晨 1万+

HashMap的5种遍历

HashMap继承AbstractMap抽象类,实现了Map、Cloneable、Serializable等接口。 HashMap的5种遍历方式有以下: 1、 通过ForEach循环进行遍历 mport java.io.IOException; import java.util.HashMap; import java.util.Map; public class Test { pu...

qq_31844483的博客 187

hashmap遍历总结

public static void main(String[] args) { Map<String,String> map=new HashMap<String,String>(); map.put("1", "value1"); map.put("2", "value2"); map.put("3", "value...

upc_dyq的博客 93

遍历hashMap

在做周末作业时,发现hashmap的遍历掌握的不是很好,到网上查了下资料,下面是转载的一篇文章,稍加整理了下。HashMap遍历的两种方式:第一种: Map map = new HashMap(); Iterator iter = map.entrySet().iterator(); while (iter.hasNext()) {     Map.Entry entry

gaoge19861207的专栏 2732

java hashmap 遍历删除元素_java 中 HashMap 遍历与删除

HashMap的遍历方法一、这是最常见的并且在大多数情况下也是最可取的遍历方式/*** 在键值都需要时使用*/Map map = new HashMap();for (Map.Entryentry : map.entrySet()) {System.out.println("Key = " + entry.getKey() + ", Value = " +entry.getValue());}方法...

weixin_30983563的博客 2640

HashMap遍历以及遍历顺序

HashMap遍历以及遍历顺序 HashMap是Java语言中一种键值对(key-value)数据结构,但不记录key的插入顺序,如果要按照插入顺序进行遍历,则需要使用LinkedHashMap类型。 本文将介绍下HashMap的三种遍历方式,LinkedHashMap遍历方式相同! (在leetcode12. 整数转罗马数字题目中使用到HashMap遍历,遂做此记录!) HashMap结构定义如下: Map<Integer, String> map = new HashMap<Inte

The coding paradise of Vincent Lee ^_^ 4493

遍历 HashMap 的 5 种最佳方式

我们来通过示例讨论在 Java 上遍历 HashMap 的五种最佳方法 使用 Iterator 遍历 HashMap EntrySet 使用 Iterator 遍历 HashMap KeySet 使用 For-each 循环迭代 HashMap 使用 Lambda 表达式遍历 HashMap 使用 Stream API 遍历 HashMap 注:hashmap 底层是一个个的Entry组合成的数组。 entry即就是:key-value对。通过遍历每一个entry,可以达到遍历每个key-value.

小码哥222的博客 939

HashMap多种遍历方式

①entrySet()遍历map1.put("小明", 1);map1.put("小红", 2);map1.put("小张", 3);//for-each + entrySet()遍历②lambda表达式遍历map1.put("小明", 1);map1.put("小红", 2);map1.put("小张", 3);//lambda表达式遍历});

hcgeng的专栏 2102

遍历hashMap的5种方法

1.使用Iterator 遍历HashMap EntrySet 2.使用Iterator 遍历HashMap KeySet 3.使用For-each 循环迭代 HashMap 4.使用Lambda 表达式遍历HashMap 5.使用Stream API 遍历HashMap 1.使用Iterator 遍历HashMap EntrySet package com.java.tutorials.iterations; import java.util.HashMap; import

weixin_60589106的博客 2万+
上一篇: Java 可变参数
下一篇: sql 排名次
tangleisoft
博客等级 码龄16年 8粉丝 31原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值