面试官:Java 8 map 和 flatMap 的区别?大部分人答不上来!

简介: 背景栈长面试会经常问 Java 8 map 和 flatMap 的区别,大部分人都答不上来,会用 map 的都不多,还有一部分人甚至都不知道这两个玩意是干嘛用的,有的还以为我问 HashMap 和 FlatMap。。

背景

栈长面试会经常问 Java 8 map 和 flatMap 的区别,大部分人都答不上来,会用 map 的都不多,还有一部分人甚至都不知道这两个玩意是干嘛用的,有的还以为我问 HashMap 和 FlatMap。。


这里所问的 map 和 flatMap 并不是集合,它们都是 Stream 流接口中的方法,如果你没用过,我估计在座的各位也有点晕,那么今天栈长就给大家扫个盲,以实际案例来剖析这两个玩意,让你面试的时候再也不怕问了!


如图所示:

image.png

在 Java 8 Stream(流)接口中有 8 个特别有意思的方法,其实就是分为两大类:


map


flatMap


现在知道这两个玩意的来路了吧?!


其中,xxToXxx 就是转换为不同的类型的流。另外,Stream 系列我之前写过一个专题了,这里不再展开,不懂的关注公众号Java技术栈,然后在公众号 Java 教程菜单中阅读。


map

map 方法的作用:


对流中的每个元素进行转换


比如现在有一个 List<String> 集合:


private static List<String> LIST = Arrays.asList("h

我想让每个元素后面都加上 "---":

/**
 * map 转换
 * @author: 栈长
 * @from: 公众号Java技术栈
 */
private static void map() {
    List<String> mapList = LIST.stream().map(e -> e.concat("---")).collect(Collectors.toList());
    mapList.forEach(System.out::print);
    System.out.println("\nmap list size: " + mapList.size());
    System.out.println();
}1.

1)先把 List 转换为 Stream;


2)调用 Stream.map 方法对 Stream 中的每个元素再封装操作一遍;


3)把 Stream<Stream> 转换为 List;


输出结果:


=====map list===== https://---www---.---javastack---.---cn--- map list size: 6


结果符合预期。


另外,我将 Java 8知识点我也整理到了小程序,都是面试常考的,大家可以在Java面试库小程序在线刷题。


如果 List 中的元素都是整数型:


private static List<String> NUMBERS_LIST = Arrays.asList("22", "19", "89", "90");

那么就可以 直接使用内置的 mapToXxx 方法,这里以 mapToLong 演示:

image.png

<R> Stream<R> map(Function<? super T, ? extends R> mapper);

LongStream mapToLong(ToLongFunction<? super T> mapper);

map 和 mapToXxx 的返回类型是不一样的。


本文所有完整示例源代码已经上传:


https://github.com/javastacks/javastack


flatMap

flatMap 方法的作用:


flat 是平铺的意思,flatMap 即对流中每个元素进行平铺后,形成多个流合在一起


比如现在有 3 个字符串数组:

image.png

<R> Stream<R> map(Function<? super T, ? extends R> mapper);

<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);

其参数是不一样的,map 前、后的每个元素都是 R 类型,flatMap 前、后的每个元素由原来的 R 类型都变成了 Stream 类型。


再小小总结下:


map 适用于对每个元素进行简单的转换,flatMap 适用于对数组流进行平铺后合并,两个方法的应用场景不一样。


所以,你学废了吗?赶紧用在项目中吧,提升自己的硬实力,让同事对你刮目相看!再啰嗦一句,对 Java 8 新增的知识点还不会用的可以关注公众号:Java技术栈,在后台回复:java,Java 8+ 系列教程我都写了一堆了。


本文所有完整示例源代码已经上传:


https://github.com/javastacks/javastack


欢迎 Star 学习,后面 Java 示例都会在这上面提供!


好了,今天的分享就到这里了,后面栈长会分享更多好玩的 Java 技术和最新的技术资讯,关注公众号Java技术栈第一时间推送,我也将主流 Java 面试题和参考答案都整理好了,在公众号后台回复关键字 "面试" 进行刷题。


最后,觉得我的文章对你用收获的话,动动小手,给个在看、转发,原创不易,栈长需要你的鼓励。

目录
相关文章
|
2天前
|
存储 JavaScript 前端开发
快速掌握WeakMap与Map的区别
快速掌握WeakMap与Map的区别
|
3天前
|
Java
Java代码解释++i和i++的五个主要区别
本文介绍了前缀递增(++i)和后缀递增(i++)的区别。两者在独立语句中无差异,但在赋值表达式中,i++ 返回原值,++i 返回新值;在复杂表达式中计算顺序不同;在循环中虽结果相同但使用方式有别。最后通过 `Counter` 类模拟了两者的内部实现原理。
Java代码解释++i和i++的五个主要区别
|
11天前
|
Java
通过Java代码解释成员变量(实例变量)和局部变量的区别
本文通过一个Java示例,详细解释了成员变量(实例变量)和局部变量的区别。成员变量属于类的一部分,每个对象有独立的副本;局部变量则在方法或代码块内部声明,作用范围仅限于此。示例代码展示了如何在类中声明和使用这两种变量。
|
23天前
|
Java
Java基础之 JDK8 HashMap 源码分析(中间写出与JDK7的区别)
这篇文章详细分析了Java中HashMap的源码,包括JDK8与JDK7的区别、构造函数、put和get方法的实现,以及位运算法的应用,并讨论了JDK8中的优化,如链表转红黑树的阈值和扩容机制。
19 1
|
24天前
|
存储 JavaScript 前端开发
Set、Map、WeakSet 和 WeakMap 的区别
在 JavaScript 中,Set 和 Map 用于存储唯一值和键值对,支持多种操作方法,如添加、删除和检查元素。WeakSet 和 WeakMap 则存储弱引用的对象,有助于防止内存泄漏,适合特定场景使用。
|
27天前
|
Java 编译器 C语言
【一步一步了解Java系列】:探索Java基本类型与C语言的区别
【一步一步了解Java系列】:探索Java基本类型与C语言的区别
36 2
|
27天前
|
存储 缓存 Java
【用Java学习数据结构系列】HashMap与TreeMap的区别,以及Map与Set的关系
【用Java学习数据结构系列】HashMap与TreeMap的区别,以及Map与Set的关系
31 1
|
14天前
|
Java
Java代码解释静态代理和动态代理的区别
### 静态代理与动态代理简介 **静态代理**:代理类在编译时已确定,目标对象和代理对象都实现同一接口。代理类包含对目标对象的引用,并在调用方法时添加额外操作。 **动态代理**:利用Java反射机制在运行时生成代理类,更加灵活。通过`Proxy`类和`InvocationHandler`接口实现,无需提前知道接口的具体实现细节。 示例代码展示了两种代理方式的实现,静态代理需要手动创建代理对象,而动态代理通过反射机制自动创建。
|
16天前
|
缓存 算法 Java
Java 中线程和纤程Fiber的区别是什么?
【10月更文挑战第14天】
43 0
|
6天前
|
安全 Java
java 中 i++ 到底是否线程安全?
本文通过实例探讨了 `i++` 在多线程环境下的线程安全性问题。首先,使用 100 个线程分别执行 10000 次 `i++` 操作,发现最终结果小于预期的 1000000,证明 `i++` 是线程不安全的。接着,介绍了两种解决方法:使用 `synchronized` 关键字加锁和使用 `AtomicInteger` 类。其中,`AtomicInteger` 通过 `CAS` 操作实现了高效的线程安全。最后,通过分析字节码和源码,解释了 `i++` 为何线程不安全以及 `AtomicInteger` 如何保证线程安全。
java 中 i++ 到底是否线程安全?