Java?Stream中map與flatMap對(duì)比超詳細(xì)教程
一、核心區(qū)別對(duì)比
| 方法 | 輸入類型 | 輸出類型 | 適用場(chǎng)景 | 轉(zhuǎn)換關(guān)系 |
|---|---|---|---|---|
map() | Function<T,R> | Stream<R> | 元素的一對(duì)一轉(zhuǎn)換 | 1:1 |
flatMap() | Function<T,Stream<R>> | Stream<R> | 元素的一對(duì)多轉(zhuǎn)換并合并 | 1:N |
二、map()方法詳解
1. 基本功能
將流中的每個(gè)元素轉(zhuǎn)換為另一個(gè)對(duì)象
2. 典型應(yīng)用場(chǎng)景
- 類型轉(zhuǎn)換
- 提取對(duì)象屬性
- 數(shù)值計(jì)算
3. 示例代碼
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class MapExample {
public static void main(String[] args) {
// 示例1:字符串轉(zhuǎn)大寫
List<String> words = Arrays.asList("hello", "world");
List<String> upperCaseWords = words.stream()
.map(String::toUpperCase)
.collect(Collectors.toList());
System.out.println(upperCaseWords); // [HELLO, WORLD]
// 示例2:提取對(duì)象屬性
class User {
String name;
User(String name) { this.name = name; }
String getName() { return name; }
}
List<User> users = Arrays.asList(
new User("Alice"),
new User("Bob")
);
List<String> names = users.stream()
.map(User::getName)
.collect(Collectors.toList());
System.out.println(names); // [Alice, Bob]
}
}
三、flatMap()方法詳解
1. 基本功能
將每個(gè)元素轉(zhuǎn)換為流,然后將所有流合并為一個(gè)流
2. 典型應(yīng)用場(chǎng)景
- 處理嵌套集合
- 拆分字符串為多個(gè)元素
- 合并多個(gè)流
3. 示例代碼
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class FlatMapExample {
public static void main(String[] args) {
// 示例1:展開(kāi)嵌套集合
List<List<String>> nestedList = Arrays.asList(
Arrays.asList("Java", "Python"),
Arrays.asList("C++", "Go"),
Arrays.asList("JavaScript", "TypeScript")
);
List<String> languages = nestedList.stream()
.flatMap(List::stream)
.collect(Collectors.toList());
System.out.println(languages);
// [Java, Python, C++, Go, JavaScript, TypeScript]
// 示例2:拆分字符串為單詞
List<String> sentences = Arrays.asList(
"Hello World",
"Java Stream API"
);
List<String> words = sentences.stream()
.flatMap(sentence -> Arrays.stream(sentence.split(" ")))
.collect(Collectors.toList());
System.out.println(words);
// [Hello, World, Java, Stream, API]
}
}
四、對(duì)比使用案例
場(chǎng)景:學(xué)生選課數(shù)據(jù)處理
import java.util.*;
import java.util.stream.*;
class Student {
String name;
List<String> courses;
Student(String name, List<String> courses) {
this.name = name;
this.courses = courses;
}
List<String> getCourses() { return courses; }
}
public class CompareExample {
public static void main(String[] args) {
List<Student> students = Arrays.asList(
new Student("Alice", Arrays.asList("Math", "Physics")),
new Student("Bob", Arrays.asList("History", "Art"))
);
// 錯(cuò)誤用法:map處理嵌套集合
List<List<String>> wrongResult = students.stream()
.map(Student::getCourses)
.collect(Collectors.toList());
System.out.println("錯(cuò)誤結(jié)果:" + wrongResult);
// [[Math, Physics], [History, Art]]
// 正確用法:flatMap展開(kāi)嵌套集合
List<String> correctResult = students.stream()
.flatMap(student -> student.getCourses().stream())
.collect(Collectors.toList());
System.out.println("正確結(jié)果:" + correctResult);
// [Math, Physics, History, Art]
// 綜合應(yīng)用:統(tǒng)計(jì)所有課程數(shù)量
long courseCount = students.stream()
.flatMap(student -> student.getCourses().stream())
.count();
System.out.println("總課程數(shù):" + courseCount); // 4
}
}
五、常見(jiàn)問(wèn)題解答
Q1:什么時(shí)候該用flatMap?
當(dāng)需要處理以下結(jié)構(gòu)時(shí):
List<List<T>>→List<T>Stream<Stream<R>>→Stream<R>- 需要拆分元素為多個(gè)子元素時(shí)
Q2:可以組合使用map和flatMap嗎?
可以,常見(jiàn)組合方式:
list.stream()
.map(...) // 初步轉(zhuǎn)換
.flatMap(...) // 展開(kāi)處理
.collect(...)
Q3:如何處理多層嵌套?
使用多次flatMap:
List<List<List<String>>> deepNested = ...;
deepNested.stream()
.flatMap(List::stream) // 展開(kāi)第一層
.flatMap(List::stream) // 展開(kāi)第二層
.collect(...);
六、總結(jié)對(duì)比
| 操作 | 輸入元素 | 輸出元素?cái)?shù)量 | 最終結(jié)果結(jié)構(gòu) |
|---|---|---|---|
map | 單個(gè)元素 | 1個(gè)新元素 | 保持原流結(jié)構(gòu) |
flatMap | 單個(gè)元素 | 0-N個(gè)新元素 | 合并為單一流結(jié)構(gòu) |
選擇原則:
- 需要簡(jiǎn)單轉(zhuǎn)換單個(gè)元素 → 使用
map() - 需要展開(kāi)嵌套結(jié)構(gòu)/生成多個(gè)元素 → 使用
flatMap()
以上代碼均可直接復(fù)制到Java 8+環(huán)境中運(yùn)行,建議在IDE中實(shí)際測(cè)試觀察輸出結(jié)果,以加深理解。
到此這篇關(guān)于Java Stream中map與flatMap對(duì)比的文章就介紹到這了,更多相關(guān)Java map與flatMap對(duì)比內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java代碼規(guī)范之不合理命名與重復(fù)代碼示例詳解
這篇文章主要為大家介紹了java代碼規(guī)范之不合理命名與重復(fù)代碼示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-09-09
關(guān)于Java8新特性O(shè)ptional類的詳細(xì)解讀
Optional類是一個(gè)容器類,它可以保存類型T的值,代表這個(gè)值存在。或者僅僅保存null,表示這個(gè)值不存在,原來(lái)用 null 表示一個(gè)值不存在,現(xiàn)在Optional 可以更好的表達(dá)這個(gè)概念。并且可以避免空指針異常,需要的朋友可以參考下2023-05-05
springboot項(xiàng)目如何部署到服務(wù)器
這篇文章主要介紹了springboot項(xiàng)目如何部署到服務(wù)器問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-05-05
Java服務(wù)假死之生產(chǎn)事故的排查與優(yōu)化問(wèn)題
在服務(wù)器上通過(guò)curl命令調(diào)用一個(gè)Java服務(wù)的查詢接口,半天沒(méi)有任何響應(yīng),怎么進(jìn)行這一現(xiàn)象排查呢,下面小編給大家記一次生產(chǎn)事故的排查與優(yōu)化——Java服務(wù)假死問(wèn)題,感興趣的朋友一起看看吧2022-07-07
springmvc處理模型數(shù)據(jù)Map過(guò)程解析
這篇文章主要介紹了springmvc處理模型數(shù)據(jù)Map過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-01-01
java向es中寫入數(shù)據(jù)報(bào)錯(cuò)org.elasticsearch.action.ActionReque問(wèn)題
這篇文章主要介紹了java向es中寫入數(shù)據(jù)報(bào)錯(cuò)org.elasticsearch.action.ActionReque問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-11-11
Java中實(shí)現(xiàn)多線程的幾種方式總結(jié)
文章介紹了三種創(chuàng)建線程的方式:繼承Thread類、實(shí)現(xiàn)Runnable接口和實(shí)現(xiàn)Callable接口,并比較了它們之間的區(qū)別和優(yōu)缺點(diǎn)2025-01-01
深入Synchronized和java.util.concurrent.locks.Lock的區(qū)別詳解
本篇文章是對(duì)Synchronized和java.util.concurrent.locks.Lock的區(qū)別進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-06-06

