java中HashMap的7种遍历方式与性能的示例分析
发表于:2024-11-17 作者:千家信息网编辑
千家信息网最后更新 2024年11月17日,本篇文章给大家分享的是有关java中HashMap的7种遍历方式与性能的示例分析,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。1、遍历方
千家信息网最后更新 2024年11月17日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安全错误
数据库的锁怎样保障安全
网络安全的八大机制
有没有关于网络安全的画
财务系统服务器
天气预报软件开发文档
数据中心网络安全检查
社保客户端服务器连接失败
psdn网络技术
计算机word综合 数据库
网易我的世界粘土服务器外挂
惠山区软件开发项目信息
手游服务器多少人
有没有无盘服务器给电脑安装系统
西安游戏软件开发有限公司
汕头电商软件开发费用是多少
登录说服务器错误
国电南自软件开发岗怎么样
战地1如何购买服务器
关系数据库中数据表
有线宽带用什么服务器
服务器安全狗添加白名单
公司共享的数据库平台
苏州控制系统软件开发
大学软件开发的专业是什么
饥荒无服务器响应
erp服务器基于什么系统
服务器里边怎么获得材质包
手机网络安全宣传常识
手游有包服务器吗
数据库原理书籍版本有哪些
诺克网络技术