前言:
眼前看官们对“迭代器遍历hashmap”大致比较关注,咱们都想要知道一些“迭代器遍历hashmap”的相关知识。那么小编也在网上汇集了一些对于“迭代器遍历hashmap””的相关资讯,希望你们能喜欢,看官们快快来了解一下吧!引言
在Java编程中,HashMap是一种常用的键值对数据结构,它提供了高效的查找、插入和删除操作。然而,当涉及到遍历大量数据时,不同的遍历方法对性能的影响不可忽视。本文将通过实验数据,对比分析七种遍历HashMap的方法,并探讨各自的优缺点。
方法与数据
在实验中,我们创建了一个包含500万条记录的HashMap,并使用Spring框架的StopWatch工具来测量每种遍历方法的耗时。以下是所测试的遍历方法及其平均执行时间(单位:纳秒):
使用迭代器遍历EntrySet - 平均耗时:约37毫秒使用迭代器遍历KeySet - 平均耗时:约42毫秒使用For Each遍历EntrySet - 平均耗时:约37毫秒使用For Each遍历KeySet - 平均耗时:约42毫秒使用Lambda表达式遍历 - 平均耗时:约57毫秒使用Streams API单线程遍历 - 平均耗时:约39毫秒使用Streams API多线程遍历 - 平均耗时:约24毫秒分析与比较迭代器遍历EntrySet与For Each遍历EntrySet: 这两种方法在性能上相近,因为它们都直接访问了HashMap的entrySet(),避免了额外的get()调用。选择哪种取决于个人编码习惯,但性能差异微乎其微。迭代器遍历KeySet与For Each遍历KeySet: 这两种方法的耗时略高,原因是每次循环都需要调用map.get(key)来获取值,这增加了额外的查找开销。使用Lambda表达式遍历: Lambda表达式的耗时最高,这主要是因为Lambda引入了额外的函数调用开销,尽管代码更加简洁,但在大规模数据集上效率较低。使用Streams API单线程遍历: Streams API提供了更现代的编程模型,允许使用函数式风格的代码。然而,单线程流并未显著提高性能,反而由于流的创建和处理增加了开销。使用Streams API多线程遍历: 当利用多线程时,Streams API展现出最佳性能,这是因为并行处理可以有效分摊计算负载,尤其在多核处理器上效果明显。但需要注意的是,多线程遍历可能引入线程安全问题,特别是在修改HashMap的情况下。结论
在遍历HashMap时,如果追求性能,建议使用迭代器遍历EntrySet或For Each遍历EntrySet,它们在大多数情况下提供了最佳平衡。而当处理数据集特别庞大且运行环境支持多线程时,使用Streams API多线程遍历则是最优选择,能够充分利用现代处理器的并行处理能力。不过,在选择遍历策略时,还需综合考虑代码可读性和维护性,以及具体的业务需求。
测试源码
import org.springframework.util.StopWatch;import java.util.HashMap;import java.util.Iterator;import java.util.Map;/** * @author CQY * @version 1.0 * @date 2024/7/18 14:29 **/public class TestHashMap { public static void main(String[] args) { // 创建一个 HashMap,写入500W条记录 HashMap<Integer, Object> map = new HashMap<>(); for (int i = 0; i < 500_0000; i++) { map.put(i, "value" + i); } StopWatch stopWatch = new StopWatch("TestHashMap"); stopWatch.start("1.使用迭代器 EntrySet 的方式遍历"); Iterator<Map.Entry<Integer, Object>> iterator1 = map.entrySet().iterator(); while (iterator1.hasNext()) { Map.Entry<Integer, Object> next = iterator1.next(); Integer key = next.getKey(); Object value = next.getValue(); } stopWatch.stop(); stopWatch.start("2.使用迭代器的KeySet"); Iterator<Integer> iterator2 = map.keySet().iterator(); while (iterator2.hasNext()) { Integer key = iterator2.next(); Object value = map.get(key); } stopWatch.stop(); stopWatch.start("3.使用 For Each EntrySet 的方式进行遍历"); for (Map.Entry<Integer, Object> entry : map.entrySet()) { Integer key = entry.getKey(); Object value = entry.getValue(); } stopWatch.stop(); stopWatch.start("4.使用 For Each KeySet 的方式进行遍历"); for (Integer key : map.keySet()) { // key Object value = map.get(key); } stopWatch.stop(); stopWatch.start("5.使用 Lambda 表达式的方式进行遍历"); map.forEach((key, value) -> { // key value }); stopWatch.stop(); stopWatch.start("6.使用 Streams API 单线程的方式进行遍历"); map.entrySet().stream().forEach((integerStringEntry -> { Integer key = integerStringEntry.getKey(); Object value = integerStringEntry.getValue(); })); stopWatch.stop(); stopWatch.start("7.使用 Streams API 多线程的方式进行遍历"); map.entrySet().parallelStream().forEach((integerStringEntry -> { Integer key = integerStringEntry.getKey(); Object value = integerStringEntry.getValue(); })); stopWatch.stop(); System.out.println(stopWatch.prettyPrint()); }}StopWatch耗时打印
StopWatch 'TestHashMap': running time = 279937200 ns---------------------------------------------ns % Task name---------------------------------------------036545100 013% 1.使用迭代器 EntrySet 的方式遍历042892700 015% 2.使用迭代器的KeySet037677900 013% 3.使用 For Each EntrySet 的方式进行遍历042370800 015% 4.使用 For Each KeySet 的方式进行遍历057247300 020% 5.使用 Lambda 表达式的方式进行遍历039540800 014% 6.使用 Streams API 单线程的方式进行遍历023662600 008% 7.使用 Streams API 多线程的方式进行遍历StopWatch 'TestHashMap': running time = 276661500 ns---------------------------------------------ns % Task name---------------------------------------------035001300 013% 1.使用迭代器 EntrySet 的方式遍历043237200 016% 2.使用迭代器的KeySet037038400 013% 3.使用 For Each EntrySet 的方式进行遍历043772700 016% 4.使用 For Each KeySet 的方式进行遍历057677600 021% 5.使用 Lambda 表达式的方式进行遍历036356600 013% 6.使用 Streams API 单线程的方式进行遍历023577700 009% 7.使用 Streams API 多线程的方式进行遍历StopWatch 'TestHashMap': running time = 318431400 ns---------------------------------------------ns % Task name---------------------------------------------044152200 014% 1.使用迭代器 EntrySet 的方式遍历051133000 016% 2.使用迭代器的KeySet047733600 015% 3.使用 For Each EntrySet 的方式进行遍历051962300 016% 4.使用 For Each KeySet 的方式进行遍历058811800 018% 5.使用 Lambda 表达式的方式进行遍历036561500 011% 6.使用 Streams API 单线程的方式进行遍历028077000 009% 7.使用 Streams API 多线程的方式进行遍历
标签: #迭代器遍历hashmap