面试官上来就让手撕HashMap的7种遍历方式,当场愣住,最后只写出了3种

news2024/9/22 4:06:15

HashMap的7种遍历方式

四大类遍历方式

其实在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种遍历方式了,在工作中还是经常用得到的,所以希望小伙伴们能够记住并熟练使用哈。

文章转载自:JavaBuild

原文链接:https://www.cnblogs.com/JavaBuild/p/18045685

体验地址:引迈 - JNPF快速开发平台_低代码开发平台_零代码开发平台_流程设计器_表单引擎_工作流引擎_软件架构

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1481185.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Node.js中的缓存策略和缓存技巧

在Node.js中&#xff0c;缓存策略和缓存技巧是提升应用性能和用户体验的关键因素。通过有效地利用缓存&#xff0c;我们可以显著减少系统资源的消耗&#xff0c;加快数据访问速度&#xff0c;从而提升整体的网站性能。本文将针对Node.js中的缓存策略和缓存技巧展开深入探讨&…

Windows下卸载JDK

操作步骤&#xff1a; 直接到windows程序卸载面板进行卸载 然后删除已配置的环境变量

TDengine 研发分享:利用 Windbg 解决内存泄漏问题的实践和经验

内存泄漏是一种常见的问题&#xff0c;它会导致程序的内存占用逐渐增加&#xff0c;最终导致系统资源耗尽或程序崩溃。AddressSanitizer (ASan) 和 Valgrind 是很好的内存检测工具&#xff0c;TDengine 的 CI 过程就使用了 ASan 。不过这次内存泄漏问题发生在 Windows 下&#…

设置matplotlib的style和rcParams

在matplotlib文档中&#xff0c;有3中设置matplot的方法&#xff0c;见文档 https://matplotlib.org/stable/users/explain/customizing.html 目前用得比较多的是设置rcParams&#xff0c;而设置rcParams也有两种方式。下面以 plot的cycler为例进行说明。 cycler就是定义的一些…

13.网络游戏逆向分析与漏洞攻防-网络通信数据包分析工具-如果没有工具就创造工具

内容参考于&#xff1a; 易道云信息技术研究院VIP课 上一个内容 &#xff1a;12.游戏网络通信存在的问题 现在把游戏网络的架构看了一个小小的大概&#xff0c;可以用它的接口发数据接收数据了&#xff0c;如果真正想用它这一套东西&#xff0c;真正核心不在于它的接口而在于…

私域必备宝藏工具:多微信统一管理聚合聊天

对于私域流量运营者来说&#xff0c;如何高效管理多个微信号成为了一道难题。 不过不用担心&#xff0c;通过微信管理系统&#xff0c;可以实现多个微信同时登录&#xff0c;同一个界面内聚合聊天&#xff0c;省去来回切换账号的步骤。而且&#xff0c;还有很多非常实用且便捷…

Chrome插件 | WEB 网页数据采集和爬虫程序

无边无形的互联网遍地是数据&#xff0c;品类丰富、格式繁多&#xff0c;包罗万象。数据采集&#xff0c;或说抓取&#xff0c;就是把分散各处的内容&#xff0c;通过各种方式汇聚一堂&#xff0c;是个有讲究要思考的体力活。君子爱数&#xff0c;取之有道&#xff0c;得注意遵…

种花

分情况&#xff1a; 第一盆k种选择&#xff0c;之后全部k-1种选择 每次相乘结果对1e97取模 #include <iostream> #include <vector> #include <algorithm> using namespace std; #define endl \n const int N 1e9 7;int main() {ios::sync_with_stdio(f…

camunda7流程版本的控制和使用

1、流程定义的版本控制 从本质上讲&#xff0c;业务流程是长期运行的&#xff0c;流程实例可能会持续数周或数月。同时&#xff0c;流程实例的状态将存储到数据库中。但是&#xff0c;即使仍有正在运行的实例&#xff0c;您也可能需要更改流程定义。 流程引擎支持此功能&…

笔记73:ROS中的各种消息包

参考视频&#xff1a; 33.ROS 的标准消息包 std_msgs_哔哩哔哩_bilibili 34. ROS 中的几何包 geometry_msgs 和 传感器包 sensor_msgs_哔哩哔哩_bilibili 标准消息包&#xff1a;std_msgs常用消息包&#xff1a;common_msgs导航消息包&#xff1a;nav_msgs几何消息包&#xf…

C++数据结构与算法——二叉树的属性

C第二阶段——数据结构和算法&#xff0c;之前学过一点点数据结构&#xff0c;当时是基于Python来学习的&#xff0c;现在基于C查漏补缺&#xff0c;尤其是树的部分。这一部分计划一个月&#xff0c;主要利用代码随想录来学习&#xff0c;刷题使用力扣网站&#xff0c;不定时更…

C++——String(1)

目录 1. 为什么学习string类&#xff1f; 1.1 C语言中的字符串 1.2 相关题目 2. 标准库中的string类 2.1 string类&#xff08;了解一下&#xff09; 2.2 string类的常用接口说明 1. string类对象的常见构造 2. string类对象的容量操作 3. string类对象的访问及遍历操作…

瑞_Redis_Redis的Java客户端

文章目录 1 Redis的Java客户端1.1 Jedis快速入门1.1.1 入门案例1.1.1.1 项目构建1.1.1.2 引入依赖1.1.1.3 建立连接1.1.1.4 释放资源1.1.1.5 测试1.1.1.6 完整测试类代码 1.1.2 Jedis连接池1.1.2.1 连接池工具类1.1.2.2 改造原始代码 &#x1f64a; 前言&#xff1a;本文章为瑞…

【Java程序设计】【C00327】基于Springboot的高校教师教研信息填报系统(有论文)

基于Springboot的高校教师教研信息填报系统&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的高校教师教研信息填报系统&#xff0c;本系统有管理员、教研管理以及教研人员三种角色&#xff1b; 管理员&#xff1a…

bvh文件,人体骨骼重定向

关于两个bvh文件&#xff0c;人体骨骼重定向&#xff0c;小白记录 1、打开 Motionbuilder &#xff0c;选择 打开特定路径下的bvh文件。 绑定骨骼&#xff08;在绑定骨骼过程中&#xff0c;如果骨骼角度&#xff0c;大小之类的不方便&#xff0c;可以shift键加鼠标拖拽界面&…

Fabric V2.5 通用溯源系统——应用后端GIN框架部分设计

本节对Fabric V2.5 通用溯源系统的应用后端部分做一个简单的介绍,包括目录结构、文件作用、用户注册登录与农产品信息上链过程介绍。此节内容免费发布在TrueTechLabs Fabric学习交流QQ群。 购买专栏前请认真阅读:《Fabric项目学习笔记》专栏介绍 TrueTechLabs Fabric学习交流…

蓝桥杯刷题2

1. 修建灌木 import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner scan new Scanner(System.in);int n scan.nextInt();for (int i 1;i < n1;i){int distance Math.max(i-1,n-i);System.out.println(distance*2);}scan.close…

Node.js+Express后端,自定义接口

6分钟学会Express 后端 API 开发 Node.js 2020最新版_哔哩哔哩_bilibili 要使用Node.js和Express搭建一个简单的后台服务器&#xff0c;用于接收带有token的请求头&#xff0c;你可以按照以下步骤进行操作&#xff1a; 首先&#xff0c;确保你已经安装了Node.js和npm&#xff0…

马斯克正式起诉OpenAI和奥特曼!

就在刚刚&#xff0c;马斯克闹出来一件大事——正式起诉OpenAI和Sam Altman&#xff0c;并要求OpenAI 恢复开源GPT-4等模型&#xff01; 众所周知&#xff0c;马斯克这两年一只在推特上指责 OpenAI是CloseAI(不开源)&#xff0c;但都只是停留在口头上。 而这次马斯克动了真格。…

Qt 自定义长条进度条(类似播放器进度条)

1.运行界面 2.步骤 其实很简单。 2.1绘制底图圆角矩形 2.2绘制播放进度圆角矩形 参考&#xff1a;painter绘图 3.源码 #pragma once#include <QWidget> #include <QLabel> #include <QHBoxLayout> #include <QMouseEvent> #include <QDebug&g…