Java?Stream中map與flatMap對比超詳細教程
一、核心區(qū)別對比
| 方法 | 輸入類型 | 輸出類型 | 適用場景 | 轉(zhuǎn)換關(guān)系 |
|---|---|---|---|---|
map() | Function<T,R> | Stream<R> | 元素的一對一轉(zhuǎn)換 | 1:1 |
flatMap() | Function<T,Stream<R>> | Stream<R> | 元素的一對多轉(zhuǎn)換并合并 | 1:N |
二、map()方法詳解
1. 基本功能
將流中的每個元素轉(zhuǎn)換為另一個對象
2. 典型應(yīng)用場景
- 類型轉(zhuǎn)換
- 提取對象屬性
- 數(shù)值計算
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:提取對象屬性
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. 基本功能
將每個元素轉(zhuǎn)換為流,然后將所有流合并為一個流
2. 典型應(yīng)用場景
- 處理嵌套集合
- 拆分字符串為多個元素
- 合并多個流
3. 示例代碼
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class FlatMapExample {
public static void main(String[] args) {
// 示例1:展開嵌套集合
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]
}
}
四、對比使用案例
場景:學(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"))
);
// 錯誤用法:map處理嵌套集合
List<List<String>> wrongResult = students.stream()
.map(Student::getCourses)
.collect(Collectors.toList());
System.out.println("錯誤結(jié)果:" + wrongResult);
// [[Math, Physics], [History, Art]]
// 正確用法:flatMap展開嵌套集合
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)計所有課程數(shù)量
long courseCount = students.stream()
.flatMap(student -> student.getCourses().stream())
.count();
System.out.println("總課程數(shù):" + courseCount); // 4
}
}
五、常見問題解答
Q1:什么時候該用flatMap?
當需要處理以下結(jié)構(gòu)時:
List<List<T>>→List<T>Stream<Stream<R>>→Stream<R>- 需要拆分元素為多個子元素時
Q2:可以組合使用map和flatMap嗎?
可以,常見組合方式:
list.stream()
.map(...) // 初步轉(zhuǎn)換
.flatMap(...) // 展開處理
.collect(...)
Q3:如何處理多層嵌套?
使用多次flatMap:
List<List<List<String>>> deepNested = ...;
deepNested.stream()
.flatMap(List::stream) // 展開第一層
.flatMap(List::stream) // 展開第二層
.collect(...);
六、總結(jié)對比
| 操作 | 輸入元素 | 輸出元素數(shù)量 | 最終結(jié)果結(jié)構(gòu) |
|---|---|---|---|
map | 單個元素 | 1個新元素 | 保持原流結(jié)構(gòu) |
flatMap | 單個元素 | 0-N個新元素 | 合并為單一流結(jié)構(gòu) |
選擇原則:
- 需要簡單轉(zhuǎn)換單個元素 → 使用
map() - 需要展開嵌套結(jié)構(gòu)/生成多個元素 → 使用
flatMap()
以上代碼均可直接復(fù)制到Java 8+環(huán)境中運行,建議在IDE中實際測試觀察輸出結(jié)果,以加深理解。
到此這篇關(guān)于Java Stream中map與flatMap對比的文章就介紹到這了,更多相關(guān)Java map與flatMap對比內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
spring boot教程之產(chǎn)生的背景及其優(yōu)勢
這篇文章主要介紹了spring boot教程之產(chǎn)生的背景及其優(yōu)勢的相關(guān)資料,需要的朋友可以參考下2022-08-08
Java實現(xiàn)讀取TXT和CSV文件內(nèi)容
這篇文章主要為大家詳細介紹了如何利用Java語言實現(xiàn)讀取TXT和CSV文件內(nèi)容的功能,文中的示例代碼講解詳細,感興趣的小伙伴可以了解一下2023-02-02
Java開發(fā)SpringBoot集成接口文檔實現(xiàn)示例
這篇文章主要為大家介紹了Java開發(fā)SpringBoot如何集成接口文檔的實現(xiàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步2021-10-10
springboot @RequestBody 接收字符串實例
這篇文章主要介紹了springboot @RequestBody 接收字符串實例,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-10-10
Java數(shù)據(jù)結(jié)構(gòu)之樹和二叉樹的相關(guān)資料
這篇文章主要介紹了Java?數(shù)據(jù)結(jié)構(gòu)之樹和二叉樹相關(guān)資料,文中通過示例代碼和一些相關(guān)題目來做介紹,非常詳細。對大家的學(xué)習或工作具有一定的參考借鑒價值,需要的朋友可以參考下!2023-01-01

