Java HashMap遍历方式性能探讨「建议收藏」

Java HashMap遍历方式性能探讨

大家好,又见面了,我是全栈君。

关于HashMap的实现这里就不展开了,具体可以参考JDK7与JDK8中HashMap的实现

JDK8之前,可以使用keySet或者entrySet来遍历HashMap,JDK8中引入了map.foreach来进行遍历。

原因:

keySet其实是遍历了2次,一次是转为Iterator对象,另一次是从hashMap中取出key所对应的value。而entrySet只是遍历了一次就把key和value都放到了entry中,效率更高。如果是JDK8,使用Map.foreach方法。 

1. keySet和entrySet

1.1 基本用法

keySet:

Map map=new HashMap();
Iterator it=map.keySet().iterator();
Object key;
Object value;
while(it.hasNext()){
key=it.next();
value=map.get(key);
System.out.println(key+":"+value);
}

entrySet:

Map map=new HashMap();
Iterator it=map.entrySet().iterator();
Object key;
Object value;
while(it.hasNext()){
Map.Entry entry = (Map.Entry)it.next();
key=entry.getKey();
value=entry.getValue();
System.out.println(key+"="+value);
}

源码上看:

keySet:

final class KeyIterator extends HashIterator
        implements Iterator<K> {
        public final K next() { return nextNode().key; }
    }

entrySet:

final class EntryIterator extends HashIterator
        implements Iterator<Map.Entry<K,V>> {
        public final Map.Entry<K,V> next() { return nextNode(); }
    }

其实这里已经很明显了,当要得到某个value时,keySet还需要从HashMap中get,entrySet相比keySet少了遍历table的过程,这也是两者性能上的主要差别。

2. Map.foreach

在JDK8以后,引入了Map.foreach。

Map.foreach本质仍然是entrySet

default void forEach(BiConsumer<? super K, ? super V> action) {
        Objects.requireNonNull(action);
        for (Map.Entry<K, V> entry : entrySet()) {
            K k;
            V v;
            try {
                k = entry.getKey();
                v = entry.getValue();
            } catch(IllegalStateException ise) {
                // this usually means the entry is no longer in the map.
                throw new ConcurrentModificationException(ise);
            }
            action.accept(k, v);
        }
    }

配合lambda表达式一起使用,操作起来更加方便。

2.1 使用Java8的foreach+lambda表达式遍历Map

Map<String, Integer> items = new HashMap<>();
items.put("A", 10);
items.put("B", 20);
items.put("C", 30);
items.put("D", 40);
items.put("E", 50);
items.put("F", 60);

items.forEach((k,v)->System.out.println("Item : " + k + " Count : " + v));

items.forEach((k,v)->{
    System.out.println("Item : " + k + " Count : " + v);
    if("E".equals(k)){
        System.out.println("Hello E");
    }
});

 

Reference:

1. http://lizhuang.iteye.com/blog/2356044

2. http://blog.163.com/fw_long/blog/static/51771186201392982041337/

3. https://yq.aliyun.com/articles/44712

转载于:https://my.oschina.net/hosee/blog/1488876

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/108301.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • 客观赋权法——变异系数法

    客观赋权法——变异系数法一、变异系数法的概念变异系数法是根据统计学方法计算得出系统各指标变化程度的方法,是一种客观赋权法。根据该方法变化差异较大的指标权重较大,变化差异较小的指标权重较小,从而根据指标的统计学规律确定其重要程度。变异系数法是一种较为客观的方法,能够客观的反应指标数据的变化信息,该方法能够比较客观的求出各指标的权重。根据各评价指标当前值与目标值的变异程度来对各指标进行赋权,当各指标现有值与目标值差距较大时,说明该指标较难实现目标值,应该赋予较大的权重,反之则应该赋予较小的权重。二、变异系数法的步骤(1)原

  • TI ADI DSP 与 ARM Cortex-A 的 FIR FFT 性能对比

    TI ADI DSP 与 ARM Cortex-A 的 FIR FFT 性能对比DSP作为计算密集型的芯片,一度是FIR和FFT运算的主力芯片,而TI和ADI两大DSP芯片公司推出的DSP产品也互不相让。可以预见,随着ARM的广泛使用和性能的提高,DSP作为独立的芯片,应用场景会越来越少,也许会慢慢退出历史的舞台;而数字信号处理,会以DSPIP软核或者硬核的形式,出现在各种芯片当中。摩尔定律和制造工艺的发展,推动着芯片行业飞速前进,不进则退。

    2022年10月14日
  • spring bean之间的关系:继承;依赖「建议收藏」

    spring bean之间的关系:继承;依赖

  • python画qq图_python绘制散点图

    python画qq图_python绘制散点图qq图有两个作用:1、检验一组数据是否服从某一分布。2、检验两个分布是否服从同一分布。qq图全称是quantile-quantileplot,从名称中可以了解到是和分位数相关的图。由于最近在做数据分析时用到了,然而看了一些博客,要么是qq图讲解的比较详尽但是没有使用Python;要么是使用Python语言但是没有讲清楚原理。基于此,想写一篇博客尽量讲清楚原理并且用Python实现出来。qq图原理…

  • “儿子,千万别帮老婆做家务!”爸爸写的这封信火了

    文 | 十二朵女王 · 主播 | 维维 儿子,明天就是你的婚礼了。 我必须提醒你,一旦结了婚,你就有了自己的新家,我和你妈不用你操心,你只用竭尽全力照顾好你自己…

  • Centos下添加用户到用户组

    Centos下添加用户到用户组

    2021年10月23日

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号