面试官上来就让手撕HashMap的7种遍历方式,当场愣住,最后只写出了3种
写在开头
今天有个小伙伴私信诉苦,说面试官上来就让他手撕HashMap的7种遍历方式,最终只写出3种常用的,怀疑面试官是在故意***难。这个问题大家怎么看?

反正我个人感觉这肯定不是***难,“手撕遍历方式” 算是一个比较简单的考验方式了,而且集合的遍历又是日常开发的必备!至于要一下写出7种,大概率是考验面试者平时学习的细心与自我总结能力,只要平时认真学习过,并且在日常代码开发中善于总结,善于归纳,完完全全写的出来呀。
HashMap的7种遍历方式
其实在这篇文章“耗时3天写完的HashMap万字解析,争取一篇文章讲透它,面试官看了都直点头!”中已经很详细的介绍了HashMap的相关知识点,以及常见面试题型,今天借着小伙伴的疑问,继续来唠一唠HashMap的遍历。
四大类遍历方式
其实在JDK1.8之前,遍历的方式远没有现在这样多,为了提高开发效率,JDK1.8开始引入了Stream流、Lambda 表达式等新特性,这让很多数据结构的遍历方式也丰富了起来。
目前,常用的遍历方式可以分为如下的4大类:
 1. 迭代器方式遍历;
 2. ForEach方式遍历;
 3. Lambda 表达式遍历;
 4. Stream流方式遍历;
而这4个大类下其实又根据具体的实现形式,分为了很多小类,我们画一个思维导图直观的看一下。

1.使用迭代器EntrySet方式遍历
看过build哥之前文章的小伙伴应该对迭代器(Iterator)并不陌生,这里就不过多介绍了,感兴趣的朋友可以看这篇文章“面试官不按套路出牌,上来就让聊一聊Java中的迭代器(Iterator ),夺命连环问,怎么办?”
话不多说,我们通过一个测试案例来感受一下map.entrySet().iterator()方式的遍历吧!
【代码示例1】
public class Test {
    public static void main(String[] args) {
        HashMap<Integer, String> map = new HashMap<>();
        map.put(1, "I");
        map.put(2, "love");
        map.put(3, "Java");
        //迭代器(Iterator)EntrySet 的方式遍历
        Iterator<Map.Entry<Integer, String>> iterator = map.entrySet().iterator();
        while (iterator.hasNext()){
            Map.Entry<Integer, String> entry = iterator.next();
            System.out.println(entry.getKey()+":"+entry.getValue());
        }
    }
}
输出:
1:I
2:love
3:Java
这种方式,使用迭代器将map结合中的元素遍历出来,通过iterator.next()把对象的 key 和 value 值都放入到了 Entry 对象中。
2.使用迭代器KeySet方式遍历
这种方式与上一种几乎一样,都是借助迭代器进行的遍历,只是迭代器提供的另一种先获取key的形式,我们依旧写一个测试类来学习一下。
【代码示例2】
public class Test {
    public static void main(String[] args) {
        HashMap<Integer, String> map = new HashMap<>();
        map.put(1, "I");
        map.put(2, "love");
        map.put(3, "Java");
        //迭代器(Iterator)KeySet 的方式遍历
        Iterator<Integer> iterator = map.keySet().iterator();
        while (iterator.hasNext()){
            Integer key = iterator.next();
            System.out.println(key+":"+map.get(key));
        }
    }
}
输出:
1:I
2:love
3:Java
虽然,两种方式输出的结果相同,但细心的朋友其实能够发现,通过keySet()遍历出来的只是键值对的key,我们要想完整的获取整个键值对数据,还需要通过HashMap的get方法,这样一来相当于又遍历了一遍,性能上自然逊色于entrySet()方式。
3.ForEach中EntrySet方式遍历
for循环我们应该都非常的熟悉,而for-each的写法,我们通常称之为增强for循环,代码相对简洁,是我们日常开发中比较常用的遍历方式,而在HashMap中我们同样可以结合for-each进行键值对遍历,看下面的代码。
【代码示例3】
public class Test {
    public static void main(String[] args) {
        HashMap<Integer, String> map = new HashMap<>();
        map.put(1, "I");
        map.put(2, "love");
        map.put(3, "Java");
        //for-each结合EntrySet 的方式遍历
        for (Map.Entry<Integer, String> entry : map.entrySet()) {
            System.out.println(entry.getKey()+":"+entry.getValue());
        }
    }
}
输出:
1:I
2:love
3:Java
怎么样?代码是不是简洁的多!这种方式同样是将遍历到的键值对存于map的entry对象中,然后通过get方法获取。
4.ForEach中KeySet方式遍历
话不多说,直接上代码!
【代码示例4】
public class Test {
    public static void main(String[] args) {
        HashMap<Integer, String> map = new HashMap<>();
        map.put(1, "I");
        map.put(2, "love");
        map.put(3, "Java");
        //for-each结合KeySet 的方式遍历
        for (Integer integer : map.keySet()) {
            System.out.println(integer+":"+map.get(integer));
        }
    }
}
输出:
1:I
2:love
3:Java
代码同样很简洁,输出结果一致,仔细观察的朋友可能会发现,这里面虽然没有迭代器,但其实底层依旧是通过迭代器实现,我们看这样的一段代码:
【代码示例5】
for (String str : list) {
    System.out.print(str + ",");
}
【反编译】
Iterator var3 = list.iterator();
while(var3.hasNext()) {
    String str = (String)var3.next();
    System.out.print(str + ",");
}
反编译后我们可以看得出,底层的实现就是迭代器,而这个for-each的写法不过是Java的一个语法糖罢了!
5.Lambda方式遍历
Lambda 表达式是推动 Java 8 发布的最重要新特性,它作为一种匿名函数,使得java8拥有了把函数作为参数传递进方法中的能力。
语法格式
(parameters) -> expression 或
(parameters) ->{ statements; }
【代码示例6】
public class Test {
    public static void main(String[] args) {
        HashMap<Integer, String> map = new HashMap<>();
        map.put(1, "I");
        map.put(2, "love");
        map.put(3, "Java");
        //Lambda方式遍历
        map.forEach((key,value) ->{
            System.out.println(key+":"+value);
        });
    }
}
输出:
1:I
2:love
3:Java
6.Streams API 单线程场景下遍历方式
Java8的另外一个新特性就是stream流,可以通过流进行数据的检索、筛选、统计、排序等操作,由于它的方法参数都是函数式接口类型,因此,它通常和Lambda 配合使用。上代码!
流的使用有2种场景:
1,stream 串行流
2,parallelStream 并行流,可多线程执行
【代码示例7】
public class Test {
    public static void main(String[] args) {
        HashMap<Integer, String> map = new HashMap<>();
        map.put(1, "I");
        map.put(2, "love");
        map.put(3, "Java");
        //Streams API 单线程时的遍历方式
        map.entrySet().stream().forEach((entry)->{
            System.out.println(entry.getKey()+":"+entry.getValue());
        });
    }
}
输出:
1:I
2:love
3:Java
7.Streams API 多线程场景下遍历方式
【代码示例8】
public class Test {
    public static void main(String[] args) {
        HashMap<Integer, String> map = new HashMap<>();
        map.put(1, "I");
        map.put(2, "love");
        map.put(3, "Java");
        //Streams API 多线程场景下遍历方式
        map.entrySet().parallelStream().forEach((entry)->{
            System.out.println(entry.getKey()+":"+entry.getValue());
        });
    }
}
输出:
1:I
2:love
3:Java
看完了stream流的遍历方式后,我们可以看到,通过底层的实现,确实让我们的遍历方式更加丰富,并且提升了整个代码的流畅性与可读性。
总结
以上就是HashMap中常用的7种遍历方式了,在工作中还是经常用得到的,所以希望小伙伴们能够记住并熟练使用哈。
结尾彩蛋
如果本篇博客对您有一定的帮助,大家记得留言+点赞+收藏呀。原创不易,转载请联系Build哥!

如果您想与Build哥的关系更近一步,还可以关注俺滴公众号“JavaBuild888”,在这里除了看到《Java成长计划》系列博文,还有提升工作效率的小笔记、读书心得、大厂面经、人生感悟等等,欢迎您的加入!
面试官上来就让手撕HashMap的7种遍历方式,当场愣住,最后只写出了3种的更多相关文章
- HashMap的两种遍历方式
		
HashMap的两种遍历方式 HashMap存储的是键值对:key-value . java将HashMap的键值对作为一个整体对象(java.util.Map.Entry)进行处理,这优化了Hash ...
 - HashMap概述及其三种遍历方式
		
一.HashMap概述: 1.HashMap是一个散列表,它存储的是键值对(key-value)映射: 2.HashMap继承AbstractMap,实现了Map,Cloneable,Serializ ...
 - HashMap 中7种遍历方式的性能分析
		
随着 JDK 1.8 Streams API 的发布,使得 HashMap 拥有了更多的遍历的方式,但应该选择那种遍历方式?反而成了一个问题. 本文先从 HashMap 的遍历方法讲起,然后再从性能. ...
 - HashMap 的 7 种遍历方式与性能分析
		
前言 随着 JDK 1.8 Streams API 的发布,使得 HashMap 拥有了更多的遍历的方式,但应该选择那种遍历方式?反而成了一个问题. 本文先从 HashMap 的遍历方法讲起,然后再从 ...
 - HashMap两种遍历方式的深入研究
		
转自:http://swiftlet.net/archives/1259 HashMap的遍历有两种方式,如下所示:第一种利用entrySet的方式: 1 2 3 4 5 6 7 Map map ...
 - Java中的HashMap的2种遍历方式比较
		
首先我们准备数据,准备一个map Map<String, String> map = new HashMap<String, String>(); for (int i = 0 ...
 - Java HashMap 四种遍历方式
		
HashMap遍历方式包含以下4种: 1.遍历KeySet,再通过Key来getValue. 2.使用entrySet的迭代器. 3.foreach entrySet的方式. 3.foreache v ...
 - 谨慎使用keySet:对于HashMap的2种遍历方式比较
		
HashMap存储的是键值对,所以一般情况下其遍历同List及Set应该有所不同. 但java巧妙的将HashMap的键值对作为一个整体对象(java.util.Map.Entry)进行处理,这优化了 ...
 - 手撕HashMap
		
前言: 平时工作的时候,用的最多的就是ArrayList和HashMap了,今天看了遍HashMap的源码,决定自己手写一遍HashMap. 一.创建MyHashMap接口 我们首先创建一 ...
 - Java HashMap两种遍历方式
		
第一种: Map map = new HashMap(); Iterator iter = map.entrySet().iterator(); while (iter.hasNext()) { Ma ...
 
随机推荐
- CentOS8 设置开机自动登录账户的方法
			
CentOS8 设置开机自动登录账户的方法 修改/etc/gdm/custom.conf文件, 并且添加内容即可. vim /etc/gdm/custom.conf # 在配置节下添加如下内容. [d ...
 - pytest-xdist分布式
			
使用pytest框架运行每条case的时候,都是上一条运行结束才会运行下一条,要是有成千上百条case 且每条运行2s那就是2*总条数,会浪费大量的时间和人力.为了节约时间和人力成本,pytest提供 ...
 - js中forEach的用法、forEach如何跳出循环、forEach与for之间的区别
			
定义和用法 forEach() 调用数组的每个元素,并将元素传递给回调函数. 注意: forEach() 对于空数组是不会执行回调函数的. 用法: array.forEach(function(cur ...
 - js计算两个时间相差多少分钟
			
<script> var str = "2020-02-04" console.log(str) console.log(str.replace(/-/g, " ...
 - 【K哥爬虫普法】淘宝一亿快递信息泄漏,有人正在盯着你的网购!
			
我国目前并未出台专门针对网络爬虫技术的法律规范,但在司法实践中,相关判决已屡见不鲜,K 哥特设了"K哥爬虫普法"专栏,本栏目通过对真实案例的分析,旨在提高广大爬虫工程师的法律意识, ...
 - 压缩软件 WinRAR 去广告
			
别去中国的那个代理网站下载 去国外的官网下载英文版或者湾湾版的, 这样用网上的rarreg.key文件方式就没有广告了, 不然中国的就是有广告. 这里是湾湾版的链接: https://pan.baid ...
 - win10家庭版禁用更新
			
前言 2020年初因为疫情在家远程办公,而我老家没有电脑,先后向两位大学生借了两台电脑来办公,发现一个现象:他们的电脑系统都是家庭版,也就是刚买电脑时安装的win10家庭版.也问了其它几位计算机专业的 ...
 - 从 WebStorm 转到 VSCode!使用一周体验报告
			
前言 最近我的 Jetbrains 开源项目授权到期了,想要续订的时候发现 Jetbrains 提高了开源项目申请门槛,我的 StarBlog 项目因为名字里包含 blog 这个词无法申请,虽然我在 ...
 - python实现GUI自动化(控制鼠标)|屏幕快照&图像识别基础
			
1.GUI自动化 ●GUI自动化就是写程序直接控制键盘和鼠标.这些程序可以控制其他应用,向它们发送虚拟的击键和鼠标点击,就像你自己坐在计算机前与应用交互-样.这种技术被称为"图形用户界面自动 ...
 - workman在线五子棋
			
一.下载安装workman,地址:https://github.com/walkor/workerman composer require workerman/workerman 二.cd到worke ...