Java?Stream?API詳解與使用示例詳解
本文全面介紹了 Java Stream API 的概念、功能以及如何在 Java 中有效地使用它進行集合和數(shù)據(jù)流的處理。通過詳細解釋和示例,文章展示了 Java Stream API 在簡化代碼、提高效率以及支持函數(shù)式編程方面的優(yōu)勢。文中還比較了 Java Stream API 與其他集合處理庫的異同,強調(diào)了其在現(xiàn)代 Java 開發(fā)中的重要性和實用性。
一、Java Stream API介紹
1. Java Stream API簡述
Java Stream API 是Java 8中引入的一項功能,它允許程序員以聲明式方式處理數(shù)據(jù)集合。通過Stream API,可以對數(shù)據(jù)執(zhí)行復雜的查詢操作,而不必編寫冗余的代碼。Stream 不是數(shù)據(jù)結(jié)構(gòu),它更像是一個高級版本的Iterator。單次使用,數(shù)據(jù)只能遍歷一次,遍歷過程中你可以對數(shù)據(jù)進行過濾、排序、聚合等操作。
2. Java Stream API支持的功能
功能 | 描述 |
---|---|
filter | 過濾流中的元素,根據(jù)條件只留下滿足條件的元素 |
map | 將流中的每個元素映射成其他形式,結(jié)果是一個包含映射后結(jié)果的新流 |
sorted | 確保流中的元素在消費時的順序按照自然順序或自定義Comparator排序 |
collect | 將流轉(zhuǎn)換為其他形式,如List、Set或Map,或者是自定義的收集器 |
forEach | 遍歷流中的每個元素并執(zhí)行給定的操作 |
reduce | 通過重復處理其元素來將流減少到單個匯總結(jié)果 |
anyMatch | 檢查流中的元素是否有一個滿足給定的條件 |
allMatch | 檢查流中的元素是否全部滿足給定條件 |
noneMatch | 檢查流中的元素是否沒有滿足給定條件的 |
findFirst | 返回流中的第一個元素,如果流為空,則返回空的Optional |
limit | 截斷流,使其最大長度不超過給定數(shù)量 |
skip | 跳過流中的前n個元素,返回包含余下元素的新流 |
3. 使用Java Stream API的優(yōu)勢
功能 | Java Stream API | 傳統(tǒng)集合操作 |
---|---|---|
數(shù)據(jù)處理模式 | 聲明式,支持函數(shù)式編程 | 命令式,代碼較為復雜 |
內(nèi)存效率 | 更高,因為它是在流上直接操作 | 低,需要復制到新的數(shù)據(jù)結(jié)構(gòu) |
并發(fā)處理 | 內(nèi)建支持并發(fā)處理 | 手動處理并發(fā) |
可讀性 | 高,流操作可鏈式調(diào)用 | 低,循環(huán)和條件判斷多 |
使用場景 | 數(shù)據(jù)集合操作,大數(shù)據(jù)處理 | 小數(shù)據(jù)量操作 |
二、常用的Java Stream API功能
下面是針對每個Java Stream API函數(shù)的示例代碼:
1. filter
過濾流中的元素,根據(jù)條件只留下滿足條件的元素。
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6); List<Integer> evenNumbers = numbers.stream() .filter(n -> n % 2 == 0) .collect(Collectors.toList()); System.out.println(evenNumbers); // 輸出 [2, 4, 6]
2. map
將流中的每個元素映射成其他形式,結(jié)果是一個包含映射后結(jié)果的新流。
List<String> words = Arrays.asList("hello", "world", "java", "stream"); List<Integer> wordLengths = words.stream() .map(String::length) .collect(Collectors.toList()); System.out.println(wordLengths); // 輸出 [5, 5, 4, 6]
3. sorted
確保流中的元素在消費時的順序按照自然順序或自定義Comparator排序。
List<Integer> numbers = Arrays.asList(4, 3, 6, 1, 5, 2); List<Integer> sortedNumbers = numbers.stream() .sorted() .collect(Collectors.toList()); System.out.println(sortedNumbers); // 輸出 [1, 2, 3, 4, 5, 6]
4. collect
將流轉(zhuǎn)換為其他形式,如List、Set或Map,或者是自定義的收集器。
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David"); Set<String> nameSet = names.stream() .collect(Collectors.toSet()); System.out.println(nameSet); // 輸出 [Alice, Bob, Charlie, David]
5. forEach
遍歷流中的每個元素并執(zhí)行給定的操作。
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5); names.stream() .forEach(System.out::println); // 依次輸出 1、2、3、4、5
6. reduce
通過重復處理其元素來將流減少到單個匯總結(jié)果。
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5); int sum = numbers.stream() .reduce(0, Integer::sum); System.out.println("Sum: " + sum); // 輸出 Sum: 15
7. anyMatch
檢查流中的元素是否有一個滿足給定的條件。
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5); boolean hasEven = numbers.stream() .anyMatch(n -> n % 2 == 0); System.out.println("Has even numbers: " + hasEven); // 輸出 Has even numbers: true
8. allMatch
檢查流中的元素是否全部滿足給定條件。
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5); boolean allEven = numbers.stream() .allMatch(n -> n % 2 == 0); System.out.println("All are even: " + allEven); // 輸出 All are even: false
9. noneMatch
檢查流中的元素是否沒有滿足給定條件的。
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5); boolean noneMultipleOfTen = numbers.stream() .noneMatch(n -> n % 10 == 0); System.out.println("None are multiples of ten: " + noneMultipleOfTen); // 輸出 None are multiples of ten: true
10. findFirst
返回流中的第一個元素,如果流為空,則返回空的Optional。
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5); Optional<Integer> first = numbers.stream() .findFirst(); System.out.println("First number: " + first.orElse(-1)); // 輸出 First number: 1
11. limit
截斷流,使其最大長度不超過給定數(shù)量。
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5); List<Integer> limited = numbers.stream() .limit(3) .collect(Collectors.toList()); System.out.println(limited); // 輸出 [1, 2, 3]
12. skip
跳過流中的前n個元素,返回包含余下元素的新流。
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5); List<Integer> skipped = numbers.stream() .skip(3) .collect(Collectors.toList()); System.out.println(skipped); // 輸出 [4, 5]
這些示例展示了Java Stream API的多樣化和強大功能,使得處理集合數(shù)據(jù)更加靈活和
三、Java Stream API和類似包比較的優(yōu)勢
Java Stream API 作為Java 8及以后版本的核心特性,對集合和數(shù)據(jù)流的處理提供了強大的支持。除了Java自帶的Stream API,還有一些其他的庫或框架也提供了類似的功能,用于處理集合或者數(shù)據(jù)流。
1. 常見的Java集合處理庫
- Java Stream API - 內(nèi)置于Java 8及以上版本,提供了一種高級的處理集合的方法,支持函數(shù)式編程。
- Apache Commons Collections - 提供了豐富的集合操作工具,但主要是針對Java集合框架之前的版本設計。
- Google Guava - 提供了許多核心Java庫沒有的集合類型和工具,包括對集合的操作和新的集合類型。
- Vavr(之前稱為Javaslang)- 提供了不可變的集合類型和其他函數(shù)式編程的工具,以提高代碼的健壯性。
- Eclipse Collections(之前稱為GS Collections)- 提供了一套豐富的集合庫,以及各種性能優(yōu)化和內(nèi)存優(yōu)化的集合類型。
2. 集合處理庫之間的比較
特性 / 庫 | Java Stream API | Apache Commons Collections | Google Guava | Vavr | Eclipse Collections |
---|---|---|---|---|---|
主要優(yōu)勢 | 內(nèi)置支持,無需額外依賴 | 豐富的集合操作工具 | 強大的集合工具和新集合類型 | 不可變集合和函數(shù)式編程支持 | 高性能、豐富的集合類型 |
集合不可變性 | 不提供 | 不提供 | 提供部分不可變集合 | 所有集合默認不可變 | 提供不可變和可變集合 |
函數(shù)式編程 | 支持 | 有限支持 | 有限支持 | 完全支持 | 有限支持 |
并發(fā)支持 | 并發(fā)流處理 | 不專門針對并發(fā)優(yōu)化 | 提供并發(fā)集合 | 不提供 | 提供優(yōu)化的并發(fā)集合 |
類型安全和檢查 | 類型安全 | 類型安全 | 類型安全 | 類型安全 | 類型安全 |
學習曲線 | 中等 | 低 | 中等 | 高 | 中等 |
與Java版本兼容性 | Java 8+ | Java 1.2+ | Java 1.6+ | Java 8+ | Java 5+ |
擴展集合類型 | 無 | 提供額外集合操作 | 提供新的集合類型 | 提供函數(shù)式集合類型 | 提供豐富的集合類型 |
每個庫都有其獨特的優(yōu)點和用途。Java Stream API是Java開發(fā)中的標準選項,無需額外依賴且與現(xiàn)代Java應用高度兼容。對于需要在老版本Java上工作的開發(fā)者,Apache Commons Collections提供了后向兼容。Google Guava和Eclipse Collections提供了高性能的集合操作,而Vavr則為喜歡函數(shù)式編程的開發(fā)者提供了很好的支持。選擇哪個庫取決于具體的項目需求、團隊的熟悉度以及對庫特性的需求。
四、Java Stream API使用總結(jié)
Java Stream API 是一個功能強大的工具,適用于處理集合和數(shù)據(jù)流。它提供了一種簡潔而高效的方法來操作數(shù)據(jù),尤其是在處理大量數(shù)據(jù)時。這個API優(yōu)化了數(shù)據(jù)處理邏輯,使開發(fā)者能夠以更少的代碼執(zhí)行復雜的數(shù)據(jù)轉(zhuǎn)換和聚合操作。利用Java Stream API,可以輕松實現(xiàn)數(shù)據(jù)過濾、排序、轉(zhuǎn)換及匯總,極大地提升了代碼的可讀性和可維護性。同時,Stream API 的函數(shù)式編程特性有助于減少錯誤和側(cè)效應,使得并發(fā)程序的編寫更為安全。通過使用Java Stream API,開發(fā)者可以寫出更簡潔、更高效、更易于維護的代碼,同時享受到函數(shù)式編程帶來的好處。
到此這篇關(guān)于Java Stream API詳解與使用示例詳解的文章就介紹到這了,更多相關(guān)Java Stream API使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
教你用Springboot實現(xiàn)攔截器獲取header內(nèi)容
項目中遇到一個需求,對接上游系統(tǒng)是涉及到需要增加請求頭,請求頭的信息是動態(tài)獲取的,需要動態(tài)從下游拿到之后轉(zhuǎn)給上游,文中非常詳細的介紹了該需求的實現(xiàn),需要的朋友可以參考下2021-05-05解決IntelliJ IDEA中鼠標拖動選擇為矩形區(qū)域問題
這篇文章主要介紹了解決IntelliJ IDEA中鼠標拖動選擇為矩形區(qū)域問題,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-10-10快速校驗實體類時,@Valid,@Validated,@NotNull注解無效的解決
這篇文章主要介紹了快速校驗實體類時,@Valid,@Validated,@NotNull注解無效的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-10-10Java元素排序Comparable與Comparator的區(qū)別
這篇文章主要介紹了Java元素排序Comparable與Comparator的區(qū)別,二者都是頂級的接口,但擁有的方法和用法是不同的,下面我們分別來看看具體是怎樣的區(qū)別吧2022-05-05java實現(xiàn)查找PDF關(guān)鍵字所在頁碼及其坐標
這篇文章主要介紹了java實現(xiàn)查找PDF關(guān)鍵字所在頁碼及其坐標的方法,本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下2019-09-09Spring注解中@Configuration和@Component到底有啥區(qū)別
之前一直搞不清@Component和@Configuration這兩個注解到底有啥區(qū)別,一直認為被這兩修飾的類可以被Spring實例化嘛,最近終于弄明白了,這篇文章主要給大家介紹了關(guān)于Spring注解中@Configuration和@Component到底有啥區(qū)別的相關(guān)資料,需要的朋友可以參考下2023-04-04spring-boot-maven-plugin?配置有啥用
這篇文章主要介紹了spring-boot-maven-plugin?配置是干啥的,這個是SpringBoot的Maven插件,主要用來打包的,通常打包成jar或者war文件,本文通過示例代碼給大家介紹的非常詳細,需要的朋友可以參考下2022-08-08