java中HashMap的7种遍历方式与性能的示例分析
发表于:2024-11-18 作者:千家信息网编辑
千家信息网最后更新 2024年11月18日,本篇文章给大家分享的是有关java中HashMap的7种遍历方式与性能的示例分析,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。1、遍历方
千家信息网最后更新 2024年11月18日java中HashMap的7种遍历方式与性能的示例分析
本篇文章给大家分享的是有关java中HashMap的7种遍历方式与性能的示例分析,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。
1、遍历方式
1.1 迭代器 EntrySet
/** * 1. 迭代器 EntrySet */@Testpublic void test1() { Mapmap = new HashMap<>(); map.put(1, "Java"); map.put(2, "JavaSE"); map.put(3, "JavaEE"); map.put(4, "Spring"); map.put(5, "SpringMVC"); map.put(6, "MyBatis"); Iterator > iterator = map.entrySet().iterator(); while (iterator.hasNext()) { Map.Entry entry = iterator.next(); System.out.println(entry.getKey() + ":" + entry.getValue()); }}
1.2 迭代器 KeySet
/** * 2. 迭代器 KeySet */@Testpublic void test2() { Mapmap = new HashMap<>(); map.put(1, "Java"); map.put(2, "JavaSE"); map.put(3, "JavaEE"); map.put(4, "Spring"); map.put(5, "SpringMVC"); map.put(6, "MyBatis"); Iterator iterator = map.keySet().iterator(); while (iterator.hasNext()) { Integer key = iterator.next(); System.out.println(key + ":" + map.get(key)); }}
1.3 ForEach EntrySet
/** * 3. ForEach EntrySet */@Testpublic void test3() { Mapmap = new HashMap<>(); map.put(1, "Java"); map.put(2, "JavaSE"); map.put(3, "JavaEE"); map.put(4, "Spring"); map.put(5, "SpringMVC"); map.put(6, "MyBatis"); for (Map.Entry entry : map.entrySet()) { System.out.println(entry.getKey() + ":" + entry.getValue()); }}
1.4 ForEach KeySet
/** * 4. ForEach KeySet */@Testpublic void test4() { Mapmap = new HashMap<>(); map.put(1, "Java"); map.put(2, "JavaSE"); map.put(3, "JavaEE"); map.put(4, "Spring"); map.put(5, "SpringMVC"); map.put(6, "MyBatis"); for (Integer key : map.keySet()) { System.out.println(key + ":" + map.get(key)); }}
1.5 Lambda 表达式
/** * 5. Lambda 表达式 */@Testpublic void test5() { Mapmap = new HashMap<>(); map.put(1, "Java"); map.put(2, "JavaSE"); map.put(3, "JavaEE"); map.put(4, "Spring"); map.put(5, "SpringMVC"); map.put(6, "MyBatis"); map.forEach((key, value) -> { System.out.println(key + ":" + value); });}
1.6 Stream API 单线程
/** * 6. Stream API 单线程 */@Testpublic void test6() { Mapmap = new HashMap<>(); map.put(1, "Java"); map.put(2, "JavaSE"); map.put(3, "JavaEE"); map.put(4, "Spring"); map.put(5, "SpringMVC"); map.put(6, "MyBatis"); map.entrySet().stream().forEach((entry) -> { System.out.println(entry.getKey() + ":" + entry.getValue()); });}
1.7 Stream API 多线程
/** * 7. Stream API 多线程 */@Testpublic void test7() { Mapmap = new HashMap<>(); map.put(1, "Java"); map.put(2, "JavaSE"); map.put(3, "JavaEE"); map.put(4, "Spring"); map.put(5, "SpringMVC"); map.put(6, "MyBatis"); map.entrySet().parallelStream().forEach((entry) -> { System.out.println(entry.getKey() + ":" + entry.getValue()); });}
1.8 代码汇总
/** * HashMap 的 7 种遍历方式 * @ClassName HashMapTraverse * @Author YH * @Date 2021/11/12 * @Version 1.0 */public class HashMapTraverseTest { /** * 1. 迭代器 EntrySet */ @Test public void test1() { Mapmap = new HashMap<>(); map.put(1, "Java"); map.put(2, "JavaSE"); map.put(3, "JavaEE"); map.put(4, "Spring"); map.put(5, "SpringMVC"); map.put(6, "MyBatis"); Iterator > iterator = map.entrySet().iterator(); while (iterator.hasNext()) { Map.Entry entry = iterator.next(); System.out.println(entry.getKey() + ":" + entry.getValue()); } } /** * 2. 迭代器 KeySet */ @Test public void test2() { Map map = new HashMap<>(); map.put(1, "Java"); map.put(2, "JavaSE"); map.put(3, "JavaEE"); map.put(4, "Spring"); map.put(5, "SpringMVC"); map.put(6, "MyBatis"); Iterator iterator = map.keySet().iterator(); while (iterator.hasNext()) { Integer key = iterator.next(); System.out.println(key + ":" + map.get(key)); } } /** * 3. ForEach EntrySet */ @Test public void test3() { Map map = new HashMap<>(); map.put(1, "Java"); map.put(2, "JavaSE"); map.put(3, "JavaEE"); map.put(4, "Spring"); map.put(5, "SpringMVC"); map.put(6, "MyBatis"); for (Map.Entry entry : map.entrySet()) { System.out.println(entry.getKey() + ":" + entry.getValue()); } } /** * 4. ForEach KeySet */ @Test public void test4() { Map map = new HashMap<>(); map.put(1, "Java"); map.put(2, "JavaSE"); map.put(3, "JavaEE"); map.put(4, "Spring"); map.put(5, "SpringMVC"); map.put(6, "MyBatis"); for (Integer key : map.keySet()) { System.out.println(key + ":" + map.get(key)); } } /** * 5. Lambda 表达式 */ @Test public void test5() { Map map = new HashMap<>(); map.put(1, "Java"); map.put(2, "JavaSE"); map.put(3, "JavaEE"); map.put(4, "Spring"); map.put(5, "SpringMVC"); map.put(6, "MyBatis"); map.forEach((key, value) -> { System.out.println(key + ":" + value); }); } /** * 6. Stream API 单线程 */ @Test public void test6() { Map map = new HashMap<>(); map.put(1, "Java"); map.put(2, "JavaSE"); map.put(3, "JavaEE"); map.put(4, "Spring"); map.put(5, "SpringMVC"); map.put(6, "MyBatis"); map.entrySet().stream().forEach((entry) -> { System.out.println(entry.getKey() + ":" + entry.getValue()); }); } /** * 7. Stream API 多线程 */ @Test public void test7() { Map map = new HashMap<>(); map.put(1, "Java"); map.put(2, "JavaSE"); map.put(3, "JavaEE"); map.put(4, "Spring"); map.put(5, "SpringMVC"); map.put(6, "MyBatis"); map.entrySet().parallelStream().forEach((entry) -> { System.out.println(entry.getKey() + ":" + entry.getValue()); }); }}
2、性能分析
使用 Oracle 官方提供的性能测试工具 JMH(Java Microbenchmark Harness,JAVA 微基准测试套件)来测试一下这 7 种循环的性能。
使用 JMH 进行性能基准测试
2.1 引入依赖
org.openjdk.jmh jmh-core 1.23 org.openjdk.jmh jmh-generator-annprocess 1.23 provided
2.2 编写测试类
直接复制粘贴即可!
/** * @ClassName HashMapCycleTest * @Author YH * @Date 2021/11/12 * @Version 1.0 */@BenchmarkMode(Mode.AverageTime) // 测试完成时间@OutputTimeUnit(TimeUnit.NANOSECONDS)@Warmup(iterations = 2, time = 1, timeUnit = TimeUnit.SECONDS) // 预热 2 轮,每次 1s@Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS) // 测试 5 轮,每次 1s@Fork(1) // fork 1 个线程@State(Scope.Thread) // 每个测试线程一个实例public class HashMapCycleTest { /** * 类加载时赋值 */ static Mapmap = new HashMap() {{ // 添加数据 for (int i = 0; i < 100; i++) { put(i, "val:" + i); } }}; public static void main(String[] args) throws RunnerException { // 启动基准测试 Options opt = new OptionsBuilder() // 要导入的测试类 .include(HashMapCycleTest.class.getSimpleName()) // 输出测试结果的文件 .output("D:/JAVA/面试/workplace/interview/jmh-hashMap.log") .build(); // 执行测试 new Runner(opt).run(); } /** * 迭代器 EntrySet */ @Benchmark public void entrySet() { // 遍历 Iterator > iterator = map.entrySet().iterator(); while (iterator.hasNext()) { Map.Entry entry = iterator.next(); Integer k = entry.getKey(); String v = entry.getValue(); } } /** * ForEach EntrySet */ @Benchmark public void forEachEntrySet() { // 遍历 for (Map.Entry entry : map.entrySet()) { Integer k = entry.getKey(); String v = entry.getValue(); } } /** * 迭代器 KeySet */ @Benchmark public void keySet() { // 遍历 Iterator iterator = map.keySet().iterator(); while (iterator.hasNext()) { Integer k = iterator.next(); String v = map.get(k); } } /** * ForEach KeySet */ @Benchmark public void forEachKeySet() { // 遍历 for (Integer key : map.keySet()) { Integer k = key; String v = map.get(k); } } /** * Lambda 表达式 */ @Benchmark public void lambda() { // 遍历 map.forEach((key, value) -> { Integer k = key; String v = value; }); } /** * Stream API 单线程 */ @Benchmark public void streamApi() { // 单线程遍历 map.entrySet().stream().forEach((entry) -> { Integer k = entry.getKey(); String v = entry.getValue(); }); } /** * Stream API 多线程 * 这个不用测,可以肯定性能是最好的。 * 如果把这个加入进测试了,理论上来说性能应该是最差的(已经测试过) * 为啥这么说?因为你本来就开了好几个线程来测试其他方法了, * 你这个方法还想再多搞几个线程来提升性能已经不可能了,线程都分配完了。 * 线程上下文切换的时间会更长!!!所以不能一起测试!!! */ public void parallelStreamApi() { // 多线程遍历 map.entrySet().parallelStream().forEach((entry) -> { Integer k = entry.getKey(); String v = entry.getValue(); }); }}
2.3 测试结果
运行程序,查看输出日志!
(1)第一次
(2)第二次
(3)第三次
2.4 分析
上图解释:测试结论{测试的方法(Benchmark)、测试类型(Mode)、测试总次数(Cnt)、测试结果(Score)、误差(Error)、单位(Units)}
其中 Units 为 ns/op 意思是执行完成时间(单位为纳秒),而 Score 列为平均执行时间, ±
符号表示误差。
从以上结果可以看出,Lambda
和两个 EntrySet
的性能相近,接下来是 Stream API
单线程,然后是 KeySet
,性能最差。
从以上结果可以看出 entrySet
的性能比 keySet
的性能高出了一倍之多,因此我们应该尽量使用 entrySet
来实现 Map 集合的遍历,当然,如果熟练 Lambda
用 Lambda
更好咯,毕竟代码简洁。
如果想深入了解为啥性能会差别这么大,建议查看字节码文件进行分析。或者是使用 javap -c 类名.class
进行反编译,查看底层的实现。
以上就是java中HashMap的7种遍历方式与性能的示例分析,小编相信有部分知识点可能是我们日常工作会见到或用到的。希望你能通过这篇文章学到更多知识。更多详情敬请关注行业资讯频道。
测试
线程
性能
迭代
分析
结果
方式
时间
表达式
基准
方法
示例
最差
代码
单位
文件
更多
知识
篇文章
误差
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
扬州专业服务器服务商
可做服务器的设备
常见网络安全风险防范小知识
爱丁堡大学网络安全专业
有机质谱数据库
荒野行动如何匹配到服务器
合肥软件开发学校培训
教育软件开发项目简单介绍
物联网服务器功能分层
网络技术标兵先进事迹材料
电子类软件开发专业
网络安全题班会教案
崇明区提供数据库系统销售要求
连云港营销软件开发培训
北京erp平台网络技术
阐述软件开发瀑布模型
日本有打车软件开发
jsp聊天室数据库db
网络安全资质
华为云服务器会被攻击吗
重庆聚妍星互联网科技有限公司
软件开发相关专业怎么样
网络安全 实施情况
北京靠谱的软件开发中心
网络安全小卫士播报
南通从事软件开发工资
郑州点创科技网络技术有限公司
未建立到远程服务器
恢复数据库名
战神引擎数据库代表什么