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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • spring boot框架搭建_springboot工作原理

    spring boot框架搭建_springboot工作原理公司大部分的应用程序都使用springboot开发,作为测试人员,学习了解该框架也势在必行。此外作为想成长为测试开发的同学来说,使用springboot开发后端服务也是一项基本的技能。

    2022年8月20日
    3
  • 阿里云服务器开放端口如何设置_阿里云服务器8888端口

    阿里云服务器开放端口如何设置_阿里云服务器8888端口阿里云服务器开放端口阿里云服务器默认是只开放了部分端口,我们部署自己的服务需要监听一下80,8080等端口时,就需要自己设置安全策略,本文介绍如何设置阿里云的安全组,开放需要的端口步骤点击阿里云的的控制台点击进入云服务器点击进入安全组菜单,点击创建安全组按钮,添加一个新的安全组2.进入创建新安全组页面填写一下必要的信息,然后配置访问规则,包括入站和出站,点击手动添加一条,设置开放所有的端口,包括端口和授权对象,点击创建安全组按钮,将创建一条新的安全组出站我们也可以配置,默

    2022年10月3日
    0
  • 数据结构之数组和链表的区别

    数据结构之数组和链表的区别第一题便是数据结构中的数组和链表的区别数组(Array)一、数组特点:所谓数组,就是相同数据类型的元素按一定顺序排列的集合;数组的存储区间是连续的,占用内存比较大,故空间复杂的很大。但数组的二分查找时间复杂度小,都是O(1);数组的特点是:查询简单,增加和删除困难;1.1在内存中,数组是一块连续的区域1.2数组需要预留空间在使用前需要提前申请所占内存的大小,…

    2022年6月29日
    15
  • 如何实现动静分离

    如何实现动静分离一、动静分离我们的网站简单来说分为2种数据资源,一种是动态的数据,即PHP等程序语言实时吐出来的数据,在网页内容上主要是HTML代码,另一种则是静态资源,比如图片、css、js、视频等(当然,图片等资源也可能是实时动态生成的,比如PHP缩略图,这里就不展开讨论了)。一般网站初建,因为流量小、业务简单等原因,都默认将两种数据放到一台服务器上提供服务。访问量大到一定程度之后,就…

    2022年5月1日
    39
  • 常用和不常用端口一览表收藏

    常用和不常用端口一览表收藏

    2021年6月8日
    102
  • JavaScript日期格式化及解析

    JavaScript日期格式化及解析JavaScript开发经常需要对日期进行转换,把日期转成字符串或者从字符串生成日期。JavaScript日期对象内置了简单的日期格式化方法toString()和日期解析方法Date.parse(),这两个方法有较大的局限性,不能自定义自定义日期格式化和解析的字符串格式。下面列出一些常用的日期处理JS库。

    2022年5月25日
    38

发表回复

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

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