• 阿里巴巴建议这样遍历Map,今天就用几种方式做个比较一下看那种最好用


    ​今天不举例子了,问一句你开心吗?不开心也要记得把开心的事情放到快乐源泉小瓶子里,偶尔拿出来一一遍历看看。

    Map在我们Java程序员高频使用的一种数据结构,Map的遍历方式也有很多种,那那种方式比较高效呢,今天就带大家一起验证下。

    先说一下阿里巴巴Java开发手册的建议:

    【推荐】使用entrySet遍历Map类集合K/V,而不是用keySet方式遍历。 

    说明:keySet其实遍历了2次,一次是转换为Iterator对象,另一次是从hashMap种取出key对应的value。如果是JDK8,使用Map.forEash方法。

    1:通过for和map.entrySet()方式遍历。

    复制代码
    // Map初始化
     private  static Map initMap(int count){
            AlternativeJdkIdGenerator alternativeJdkIdGenerator = new AlternativeJdkIdGenerator();
            Map map = new HashMap<>();
            for (int i = 0; i < count; i++) {
                map.put(alternativeJdkIdGenerator.generateId().toString(),i) ;
            }
            return  map ;
        }
    复制代码
    复制代码
    int count = 1000000;
            Map map =initMap(count) ;
            // 为了计算平均值,分别循环三次进行遍历
            for (int i = 0; i < 3; i++) {
                Instant start;
                Instant end;
                start = Instant.now();
                for (Map.Entry entry : map.entrySet()) {
                    // 一般遍历map就是获取key和value
                    String  result="key为:"+entry.getKey()+",value为:"+entry.getValue();
                }
                end = Instant.now();
                System.out.println("遍历循环" + count + "次耗时:" + Duration.between(start, end).toMillis() + "ms");
            }
    复制代码

    运行三次的结果如下:(平均值:368.33ms)

     

    ​2、通过 for, Iterator 和 map.entrySet() 来遍历

    复制代码
      int count = 1000000;
            Map map =initMap(count) ;
            for (int i = 0; i < 3; i++) {
                Instant start;
                Instant end;
                start = Instant.now();
                for (Iterator> entries = map.entrySet().iterator(); entries.hasNext(); ) {
                    Map.Entry entry = entries.next();
                    String result ="key为:"+entry.getKey()+",value为:"+entry.getValue();
                }
                end = Instant.now();
                System.out.println("遍历循环" + count + "次耗时:" + Duration.between(start, end).toMillis() + "ms");
            }
    复制代码

    ​运行三次的结果如下:(平均值:339.66ms)

     

     

     ​3、通过 for 和 map.keySet() 来遍历

    复制代码
     int count = 1000000;
            Map map =initMap(count) ;
            for (int i = 0; i < 3; i++) {
                Instant start;
                Instant end;
                start = Instant.now();
                for (String key : map.keySet()) {
                    String result ="key为:"+key+",value为:"+map.get(key);
                }
                end = Instant.now();
                System.out.println("遍历循环" + count + "次耗时:" + Duration.between(start, end).toMillis() + "ms");
            }
    复制代码

    运行三次的结果如下:(平均值:379.66ms)

    ​4、通过 for,Iterator 和 map.keySet() 来遍历

    复制代码
      int count = 1000000;
            Map map =initMap(count) ;
            for (int i = 0; i < 3; i++) {
                Instant start;
                Instant end;
                start = Instant.now();
                for (Iterator key = map.keySet().iterator(); key.hasNext(); ) {
                    String k = key.next();
                    String result ="key为:"+k+",value为:"+map.get(k);
                }
                end = Instant.now();
                System.out.println("遍历循环" + count + "次耗时:" + Duration.between(start, end).toMillis() + "ms");
            }
    复制代码

    运行三次的结果如下:(平均值330.33ms)

     

     5、通过 map.forEach() 来遍历

    复制代码
    int count = 1000000;
            Map map =initMap(count) ;
            for (int i = 0; i < 3; i++) {
                Instant start;
                Instant end;
                start = Instant.now();
                map.forEach((key, value) -> {
                    String result ="key为:"+key+",value为:"+map.get(value);
                });
                end = Instant.now();
                System.out.println("遍历循环" + count + "次耗时:" + Duration.between(start, end).toMillis() + "ms");
            }
    复制代码

    ​运行三次的结果如下:(平均值506.33ms)

     

     

    ​经过上面的验证(在大批量数据的时候,数据量小的时候没测试,感觉数据量小的化耗时太小更不好比较)最好不要用map.forEach()来遍历Map。在普通的遍历方法中 entrySet() 的方法要比使用 keySet() 的方法好。【PS虽然keySet() 的平均值有时候比较小,但它的波动性比较大,所以还是考虑阿里巴巴Java开发手册的建议使用entrySet()遍历Map】。

    看过 HashMap 源码的同学应该会发现,这个遍历方式【entrySet(】在源码中也有使用,如下图所示。

     

     

     ​Spring的源码也有很多的Map,大神们遍历的方式也都基本使用entrySet()遍历如下:

     

     所以开发中也建议使用entrySet()来遍历Map。

  • 相关阅读:
    JS原型对象prototype
    每天5分钟玩转Kubernetes | 先把Kubernetes跑起来
    Microsoft Edge不能工作了,可能原因不少,那么如何修复呢
    幂等性(防重复提交)
    C++概述
    10.19QT作业
    天馈 频谱 场强 +定位,手持式信号综合分析仪---AMT950C
    Singleton Pattern 单例模式简介与 C# 示例【创建型】【设计模式来了】
    TRex学习之旅九
    JWT详细介绍
  • 原文地址:https://www.cnblogs.com/scott1102/p/17300721.html