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

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

写在开头

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

image.png

反正我个人感觉这肯定不是刁难,“手撕遍历方式” 算是一个比较简单的考验方式了,而且集合的遍历又是日常开发的必备!至于要一下写出7种,大概率是考验面试者平时学习的细心与自我总结能力,只要平时认真学习过,并且在日常代码开发中善于总结,善于归纳,完完全全写的出来呀。

HashMap的7种遍历方式

今天借着小伙伴的疑问,继续来唠一唠HashMap的遍历。

四大类遍历方式

其实在JDK1.8之前,遍历的方式远没有现在这样多,为了提高开发效率,JDK1.8开始引入了Stream流、Lambda 表达式等新特性,这让很多数据结构的遍历方式也丰富了起来。
目前,常用的遍历方式可以分为如下的4大类:

 1. 迭代器方式遍历;
 2. ForEach方式遍历;
 3. Lambda 表达式遍历;
 4. Stream流方式遍历;

而这4个大类下其实又根据具体的实现形式,分为了很多小类,我们画一个思维导图直观的看一下。
image.png

1.使用迭代器EntrySet方式遍历

看过build哥之前文章的小伙伴应该对迭代器(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哥!

image.png

目录
相关文章
|
2月前
|
存储 缓存 安全
面试题-HashMap底层原理与HashTable的区别
字节跳动面试题-HashMap底层原理与HashTable的区别
38 0
|
8月前
HashMap遍历方式
HashMap遍历方式
|
9月前
|
搜索推荐 Java API
一道Java集合排序题,HashMap排序,面试必备
一道Java集合排序题,HashMap排序,面试必备
|
22天前
|
消息中间件 存储 缓存
面试题--HashMap和TreeMap的区别和应用场景有啥区别?
然后底层调用key的hashCode()方法得出hash值; 过哈希表哈希算法,将hash值转换成数组的下标(注1),下标位置上如果没有任何元素,就把Node添加到这个位置上。如果说下标对应的位置上有值。此时,就会拿着key和链表上每个节点的key进行equal。如果所有的equals方法返回都是false,那么这个新的节点将被添加到链表的末尾。如其中有一个equals返回了true,那么这个节点的value将会被覆盖,如果最终长度大于8就会转成红黑树,红黑树插入;
21 3
|
3天前
|
存储 安全 Java
《ArrayList & HashMap 源码类基础面试题》面试官们最喜欢问的ArrayList & HashMap源码类初级问,你都会了?
《ArrayList & HashMap 源码类基础面试题》面试官们最喜欢问的ArrayList & HashMap源码类初级问,你都会了?
7 0
|
2月前
|
Python
2024年Python最新刷爆全网的动态条形图,原来5行Python代码就能实现!,2024年最新Python面试必问的HashMap
2024年Python最新刷爆全网的动态条形图,原来5行Python代码就能实现!,2024年最新Python面试必问的HashMap
2024年Python最新刷爆全网的动态条形图,原来5行Python代码就能实现!,2024年最新Python面试必问的HashMap
|
2月前
|
存储 算法 Java
如果面试也能这样说HashMap,那么就不会有那么多遗憾!(中)
如果面试也能这样说HashMap,那么就不会有那么多遗憾!
35 0
|
2月前
|
存储 算法 Java
耗时3天写完的HashMap万字解析,争取一篇文章讲透它,面试官看了都直点头!
耗时3天写完的HashMap万字解析,争取一篇文章讲透它,面试官看了都直点头!
65 3
|
9月前
|
设计模式 算法 Java
面试官:JDK1.8 HashMap扩容rehash算法是如何优化的?
本文跟大家聊一聊一个常见的面试题,那就是JDK1.8 HashMap扩容rehash算法是如何优化的?
|
2月前
|
存储 机器学习/深度学习 算法
如果面试也能这样说HashMap,那么就不会有那么多遗憾!(上)
如果面试也能这样说HashMap,那么就不会有那么多遗憾!
46 1