热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

HashMap遍历使用entrySet的效率真的比keyset高?

HashMap是一个比较常用的映射。当我们遍历的时候会怎样写呢?我一开始时这样写的:for(Strings:map.keySet()){

HashMap是一个比较常用的映射。当我们遍历的时候会怎样写呢?

我一开始时这样写的:

 for (String s : map.keySet()){
            map.get(s);
 }


当然,如果不要key也可以这样写:

 for (Object result: map.values()) {
            if (result != null){
                result.toString();        
       }
}

然而,这样写真的好吗?

某次上网看到这样的写法:

 for (Map.Entry entry: map.entrySet()) {
            if (entry != null){
                entry.getValue();
                count++;
            }
        }

大家都认可这是效率最高的遍历方法,那么为什么呢?

我首先写了简单的方法测试一下这三种方法遍历所用的时间:

 @Test
    public void test(){
        Map map = new HashMap<>();
        for (int i = 0; i<10000; i++){
            map.put("test" + i, i);
        }
        //第一种遍历
        long star1 = System.nanoTime();
        for (int i = 0; i<10000; i++){
            for (Map.Entry entry: map.entrySet()) {
                if (entry != null){
                    entry.getValue();
                }
            }
        }
        System.out.println("entrySet:" + ((System.nanoTime()-star1)/10000));
        //第二种遍历
        long star2 = System.nanoTime();
        for (int i = 0; i<10000; i++){
            for (String s : map.keySet()){
                map.get(s);
            }
        }
        System.out.println("keySet" + ((System.nanoTime()-star2)/10000));
        //第三种遍历
        long star3 = System.nanoTime();
        for (int i = 0; i<10000; i++){
            for (Object result: map.values()) {
                if (result != null){}
            }
        }
        System.out.println("values" + ((System.nanoTime()-star3)/10000));
    }

对10000个key,value的hashMap进行10000遍历,取平均值的结果:

entrySet:79827
keySet115419
values71514

可见HashMap.entrySet()方法遍历确实是快一点。那么就想知道为什么这个方法运行速度快呢?

这里需要从HashMap的数据结构说起:



如图,是hashMap的数据结构图。画成这样,程序员看一眼就很清楚结构了。首先它是基于一个可扩容的数组排列的。一般对应的key会有它的hash码,根据hash%16(数组长度)决定该条数据排列在哪个角标的后面。比如hash值为16的数据就会排在0后面,hash值18的就会排在2后面。

那么如果在hash值为16的数据put进hashMap之后,又put进一个hash值为0或者key为null的数据。此时,原先hash值为16的数据会指向新数据的next字段,从而形成一个单链表。

简单说明了hashMap数据的存储过程,再来看看这些方法是怎么遍历的:

第一种,实际就是通过map.entrySet()获取对应的Entry,然后获取Entry中的value属性。这个方法具体是怎么获取Entry的呢?

首先就是遍历数组,再遍历数组每个元素后面对应的链表,这种方式其实就是实现hashMap的原理。

第二种,首先遍历出hashMap的所有的key,再次根据key去查找对应的值,而单链表的特性大家都知道,增删快,查找慢。

第三种,只遍历value速度确实比第一种快,但实用性比较低。




HashMap相关源码参考









推荐阅读
  • HashTable与ConcurrentHashMap均可实现HashMap的功能,对外提供了键值对存储的数据结构。但是在内部结构及实现上有何区别,性能上的差异到底在哪里又是如何导致的 ... [详细]
  • 缓存这个东西就是为了提高运行速度的,由于缓存是在寸土寸金的内存里面,不是在硬盘里面,所以容量是很有限的。LRU这个算法就是把最近一次使用时间离现在时间最远的数据删除掉。先说说List:每 ... [详细]
  • 模板引擎StringTemplate的使用方法和特点
    本文介绍了模板引擎StringTemplate的使用方法和特点,包括强制Model和View的分离、Lazy-Evaluation、Recursive enable等。同时,还介绍了StringTemplate语法中的属性和普通字符的使用方法,并提供了向模板填充属性的示例代码。 ... [详细]
  • HashMap的相关问题及其底层数据结构和操作流程
    本文介绍了关于HashMap的相关问题,包括其底层数据结构、JDK1.7和JDK1.8的差异、红黑树的使用、扩容和树化的条件、退化为链表的情况、索引的计算方法、hashcode和hash()方法的作用、数组容量的选择、Put方法的流程以及并发问题下的操作。文章还提到了扩容死链和数据错乱的问题,并探讨了key的设计要求。对于对Java面试中的HashMap问题感兴趣的读者,本文将为您提供一些有用的技术和经验。 ... [详细]
  • 本篇文章给大家分享的是有关Java中怎么对HashMap按键值排序,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话 ... [详细]
  • 将学生对象和学生的归属地通过键与值存储到map集合中。importjava.util.HashMap;importjava.util.Iterator;importjava.uti ... [详细]
  • 01Map集合概述A:Map集合概述:我们通过查看Map接口描述,发现Map接口下的集合与Collection接口下的集合,它们存储数据的形式不同a:Collection中的集合 ... [详细]
  • 手写HashMap,快手面试官直呼内行
    手写HashMap,快手面试官直呼内行-手写HashMap?这么狠,面试都卷到这种程度了?第一次见到这个面试题,是在某个不方便透露姓名的Offer收割机大佬的文章:这……我当 ... [详细]
  • 本文介绍了Redis的基础数据结构string的应用场景,并以面试的形式进行问答讲解,帮助读者更好地理解和应用Redis。同时,描述了一位面试者的心理状态和面试官的行为。 ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • JDK源码学习之HashTable(附带面试题)的学习笔记
    本文介绍了JDK源码学习之HashTable(附带面试题)的学习笔记,包括HashTable的定义、数据类型、与HashMap的关系和区别。文章提供了干货,并附带了其他相关主题的学习笔记。 ... [详细]
  • 本文整理了Java面试中常见的问题及相关概念的解析,包括HashMap中为什么重写equals还要重写hashcode、map的分类和常见情况、final关键字的用法、Synchronized和lock的区别、volatile的介绍、Syncronized锁的作用、构造函数和构造函数重载的概念、方法覆盖和方法重载的区别、反射获取和设置对象私有字段的值的方法、通过反射创建对象的方式以及内部类的详解。 ... [详细]
  • 本文介绍了H5游戏性能优化和调试技巧,包括从问题表象出发进行优化、排除外部问题导致的卡顿、帧率设定、减少drawcall的方法、UI优化和图集渲染等八个理念。对于游戏程序员来说,解决游戏性能问题是一个关键的任务,本文提供了一些有用的参考价值。摘要长度为183字。 ... [详细]
  • 转载自:http:www.blogjava.netCarpenterLeearchive20160427430268.html总体介绍之所以把HashSet和HashMa ... [详细]
  • 我找到了这篇有关在Typescript中实现哈希图的帖子,除了从哈希图中删除某些内容 ... [详细]
author-avatar
埃博拉网络科技
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有