Java_Map常用的遍历方式及性能对比

HashMap为例子:

public static void main(String[] args) {
        //初始化map结构
        HashMap map= new HashMap();
        for(int i = 0;i < 10;i++){
            map.put(i, "第"+i+"个元素");
        }

        //第一种方式:keySet的增强for循环遍历方式
        long time1 = System.nanoTime();
        for(Integer key : map.keySet()){
            map.get(key);
        }
        long time2 = System.nanoTime();

        //第二种方式:keySet的Iterator遍历方式
        Iterator iterator = map.keySet().iterator();
        while(iterator.hasNext()){
            Integer key = iterator.next();
            map.get(key);
        }
        long time3 = System.nanoTime();

        //第三种方式:entrySet的增强for循环遍历方式
        for(Map.Entry entry: map.entrySet()){
            entry.getKey();
            entry.getValue();
        }
        long time4 = System.nanoTime();

        //第四种方式:entrySet的Iterator遍历方式
        Iterator> iterator2 = map.entrySet().iterator();
        Map.Entry entry;
        while(iterator2.hasNext()){
            entry = iterator2.next();
            entry.getKey();
            entry.getValue();
        }
        long time5 = System.nanoTime();

        //第五种方式:values的增强for循环遍历方式
        //values()方法的for循环遍历方式
        Collection values = map.values();
        for(String value : values){

        }
        long time6 = System.nanoTime();

        //第六种方式:values的Iterator遍历方式
        Iterator iterator3 = map.values().iterator();
        String value;
        while(iterator3.hasNext()){
            value=iterator3.next();
        }
        long time7 = System.nanoTime();

        //第七种方式:JDK 1.8支持的Lambda表达式
        map.forEach((key, value2) -> {

        });
        long time8 = System.nanoTime();

        //第七种方式:JDK 1.8支持的Lambda表达式(第二遍)
        map.forEach((key, value2) -> {

        });
        long time9 = System.nanoTime();

        System.out.println("第一种方式:keySet的增强for循环遍历方式:" + (time2-time1)/1000 + "微秒");
        System.out.println("第二种方式:keySet的Iterator遍历方式:" + (time3-time2)/1000 + "微秒");
        System.out.println("第三种方式:entrySet的增强for循环遍历方式:" + (time4-time3)/1000 + "微秒");
        System.out.println("第四种方式:entrySet的Iterator遍历方式:" + (time5-time4)/1000 + "微秒");
        System.out.println("第五种方式:values的增强for循环遍历方式:" + (time6-time5)/1000 + "微秒");
        System.out.println("第六种方式:values的Iterator遍历方式:" + (time7-time6)/1000 + "微秒");
        System.out.println("第七种方式:JDK 1.8支持的Lambda表达式:" + (time8-time7)/1000 + "微秒");
        System.out.println("第七种方式:JDK 1.8支持的Lambda表达式(第二遍)" + (time9-time8)/1000 + "微秒");
    }

数据量为10 的结果:

第一种方式:keySet的增强for循环遍历方式:187微秒
第二种方式:keySet的Iterator遍历方式:2微秒
第三种方式:entrySet的增强for循环遍历方式:18微秒
第四种方式:entrySet的Iterator遍历方式:2微秒
第五种方式:values的增强for循环遍历方式:170微秒
第六种方式:values的Iterator遍历方式:1微秒
第七种方式:JDK 1.8支持的Lambda表达式:33128微秒
第七种方式:JDK 1.8支持的Lambda表达式(第二遍)181微秒

数据量为1万的结果:

第一种方式:keySet的增强for循环遍历方式:1211微秒
第二种方式:keySet的Iterator遍历方式:625微秒
第三种方式:entrySet的增强for循环遍历方式:695微秒
第四种方式:entrySet的Iterator遍历方式:614微秒
第五种方式:values的增强for循环遍历方式:602微秒
第六种方式:values的Iterator遍历方式:384微秒
第七种方式:JDK 1.8支持的Lambda表达式:35414微秒
第七种方式:JDK 1.8支持的Lambda表达式(第二遍)721微秒 

 数据量为10万的结果:

第一种方式:keySet的增强for循环遍历方式:5696微秒
第二种方式:keySet的Iterator遍历方式:3887微秒
第三种方式:entrySet的增强for循环遍历方式:3402微秒
第四种方式:entrySet的Iterator遍历方式:2634微秒
第五种方式:values的增强for循环遍历方式:2425微秒
第六种方式:values的Iterator遍历方式:1917微秒
第七种方式:JDK 1.8支持的Lambda表达式:39311微秒
第七种方式:JDK 1.8支持的Lambda表达式(第二遍)4305微秒

 总结:

        entrySet的方式比keySet性能要好,原因在于keySet相当于遍历了2次,一次是对key的Set集合的遍历,二次是每次遍历过程都要通过key和map.get(key)来获取value值。map.get(key)的时候,底层是根据key的hashCode值经过哈希算法得到一个hash值,然后作为索引映射到对应的table数组的索引位置,这是一次密集型计算,很耗费CPU,如果有大量的元素,则会使CPU使用率飙升,影响响应速度,而entrySet()返回的set里面的元素都是Map.Enpty类型,key和value就是这个类的一个属性,entry.getKey()和entry.getValue()效率肯定很高。
        values的方式,Map的所有value的集合的Collection,只能遍历到value,很难遍历到key,所以一般不用,如果当我们只需要取得value值时,采用values来遍历效率更高。

        从上面的几种方式的for循环遍历和Iterator遍历的方式耗时结果来看,Iterator遍历的效率会比for循环效率更快一点。

        lambda表达式的方式,第一次特别的慢,之后的效率有显著提升,建议初始化放到项目启动的过程中,这样可以大大提高lambda表达式的性能。

灵感连接:Java集合篇:Map常用遍历方式 以及 性能对比_张维鹏的博客-CSDN博客

你可能感兴趣的:(java基础,java)