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

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

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

赞 (0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 2020最新版MySQL数据库面试题(一)

    2020最新版MySQL数据库面试题(一)

    2022年2月14日
  • visual studio发生了未处理的异常_灾难性故障0x8000ffff

    visual studio发生了未处理的异常_灾难性故障0x8000ffff故障说明:使用vs2010时,由于文件创建MFC类时,移除文件后重新创建正确的基类,覆盖之前创建的文件造成,在“解决方案资源管理器”点击“cpp”文件弹出该提示。解决方法:在“解决方案资源管理器”,重命名cpp文件,双击打开后,改回原名即可。

    2022年9月24日
  • vue v-if 多条件_vue列表渲染

    vue v-if 多条件_vue列表渲染v-if在模板中,可以根据条件进行渲染。条件用到的是v-if、v-else-if以及v-else来组合实现的。示例代码如下:<divid="app"><p

    2022年7月29日
  • 毕业一年

    又到毕业季,一年就这么过来了,这一年独自在北京,过的单调但也充实,就做了两件事,减肥和学习。减肥在校期间不怎么运动,偶尔跑步但抵不过吃的多,永远是饭桌上吃到最后的人,肉不停的长,最胖时90kg。去年年底的时候,有一天照镜子,捏着肚子上的肉实在看不下去,下决心减肥。左图87kg到右图71kg,体脂从25降到18左右。 减肥的过程是痛苦的,但是成就感爆棚,让人更加自信,也更加相信付出会有回报。学习看

    2022年3月11日
  • linux扩容VBoxManage

    linux扩容VBoxManage//查看虚拟磁盘空间信息,确认确实是需要扩容的虚拟硬盘。VBoxManageshowhdinfo”F:\oracleVirtualBox\workspace\centos1\centos1.vdi”//计算要扩容的空间大小,我这里是要扩展到100G(1024*1024*1024*100)。set/a1024*1024*1024//扩展虚拟硬盘空间,最后的数字替换成上面计算出的硬盘空…

    2022年6月1日
  • win7笔记本卡顿怎么解决_win10玩cf卡顿解决方法

    win7笔记本卡顿怎么解决_win10玩cf卡顿解决方法win7系统运行卡顿的解决方法?我们在操作win7系统电脑的时候,常常会遇到win7系统运行卡顿的问题。那么出现win7系统运行卡顿的问题该怎么解决呢?很多对电脑不太熟悉的小伙伴不知道win7系统运行卡顿到底该如何解决?其实只需要首先检查一下自己的电脑有没有装了多余的软件,假如是没有用的程序和那些你通过在网上下载其他程序的软件捆绑的程序,要把它卸载掉,建议不要装杀毒软件,比如360安全卫士,金山毒…

    2022年9月12日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

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