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