Java?Stream?API詳解與使用示例詳解
本文全面介紹了 Java Stream API 的概念、功能以及如何在 Java 中有效地使用它進(jìn)行集合和數(shù)據(jù)流的處理。通過(guò)詳細(xì)解釋和示例,文章展示了 Java Stream API 在簡(jiǎn)化代碼、提高效率以及支持函數(shù)式編程方面的優(yōu)勢(shì)。文中還比較了 Java Stream API 與其他集合處理庫(kù)的異同,強(qiáng)調(diào)了其在現(xiàn)代 Java 開(kāi)發(fā)中的重要性和實(shí)用性。

一、Java Stream API介紹
1. Java Stream API簡(jiǎn)述
Java Stream API 是Java 8中引入的一項(xiàng)功能,它允許程序員以聲明式方式處理數(shù)據(jù)集合。通過(guò)Stream API,可以對(duì)數(shù)據(jù)執(zhí)行復(fù)雜的查詢操作,而不必編寫(xiě)冗余的代碼。Stream 不是數(shù)據(jù)結(jié)構(gòu),它更像是一個(gè)高級(jí)版本的Iterator。單次使用,數(shù)據(jù)只能遍歷一次,遍歷過(guò)程中你可以對(duì)數(shù)據(jù)進(jìn)行過(guò)濾、排序、聚合等操作。
2. Java Stream API支持的功能
| 功能 | 描述 |
|---|---|
filter | 過(guò)濾流中的元素,根據(jù)條件只留下滿足條件的元素 |
map | 將流中的每個(gè)元素映射成其他形式,結(jié)果是一個(gè)包含映射后結(jié)果的新流 |
sorted | 確保流中的元素在消費(fèi)時(shí)的順序按照自然順序或自定義Comparator排序 |
collect | 將流轉(zhuǎn)換為其他形式,如List、Set或Map,或者是自定義的收集器 |
forEach | 遍歷流中的每個(gè)元素并執(zhí)行給定的操作 |
reduce | 通過(guò)重復(fù)處理其元素來(lái)將流減少到單個(gè)匯總結(jié)果 |
anyMatch | 檢查流中的元素是否有一個(gè)滿足給定的條件 |
allMatch | 檢查流中的元素是否全部滿足給定條件 |
noneMatch | 檢查流中的元素是否沒(méi)有滿足給定條件的 |
findFirst | 返回流中的第一個(gè)元素,如果流為空,則返回空的Optional |
limit | 截?cái)嗔鳎蛊渥畲箝L(zhǎng)度不超過(guò)給定數(shù)量 |
skip | 跳過(guò)流中的前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
過(guò)濾流中的元素,根據(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、56. reduce
通過(guò)重復(fù)處理其元素來(lái)將流減少到單個(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: 157. 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: true8. 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: false9. noneMatch
檢查流中的元素是否沒(méi)有滿足給定條件的。
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: true10. 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: 111. limit
截?cái)嗔?,使其最大長(zhǎng)度不超過(guò)給定數(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
跳過(guò)流中的前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. 常見(jiàn)的Java集合處理庫(kù)
- Java Stream API - 內(nèi)置于Java 8及以上版本,提供了一種高級(jí)的處理集合的方法,支持函數(shù)式編程。
- Apache Commons Collections - 提供了豐富的集合操作工具,但主要是針對(duì)Java集合框架之前的版本設(shè)計(jì)。
- Google Guava - 提供了許多核心Java庫(kù)沒(méi)有的集合類型和工具,包括對(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)置支持,無(wú)需額外依賴 | 豐富的集合操作工具 | 強(qiáng)大的集合工具和新集合類型 | 不可變集合和函數(shù)式編程支持 | 高性能、豐富的集合類型 |
| 集合不可變性 | 不提供 | 不提供 | 提供部分不可變集合 | 所有集合默認(rèn)不可變 | 提供不可變和可變集合 |
| 函數(shù)式編程 | 支持 | 有限支持 | 有限支持 | 完全支持 | 有限支持 |
| 并發(fā)支持 | 并發(fā)流處理 | 不專門(mén)針對(duì)并發(fā)優(yōu)化 | 提供并發(fā)集合 | 不提供 | 提供優(yōu)化的并發(fā)集合 |
| 類型安全和檢查 | 類型安全 | 類型安全 | 類型安全 | 類型安全 | 類型安全 |
| 學(xué)習(xí)曲線 | 中等 | 低 | 中等 | 高 | 中等 |
| 與Java版本兼容性 | Java 8+ | Java 1.2+ | Java 1.6+ | Java 8+ | Java 5+ |
| 擴(kuò)展集合類型 | 無(wú) | 提供額外集合操作 | 提供新的集合類型 | 提供函數(shù)式集合類型 | 提供豐富的集合類型 |
每個(gè)庫(kù)都有其獨(dú)特的優(yōu)點(diǎn)和用途。Java Stream API是Java開(kāi)發(fā)中的標(biāo)準(zhǔn)選項(xiàng),無(wú)需額外依賴且與現(xiàn)代Java應(yīng)用高度兼容。對(duì)于需要在老版本Java上工作的開(kāi)發(fā)者,Apache Commons Collections提供了后向兼容。Google Guava和Eclipse Collections提供了高性能的集合操作,而Vavr則為喜歡函數(shù)式編程的開(kāi)發(fā)者提供了很好的支持。選擇哪個(gè)庫(kù)取決于具體的項(xiàng)目需求、團(tuán)隊(duì)的熟悉度以及對(duì)庫(kù)特性的需求。
四、Java Stream API使用總結(jié)
Java Stream API 是一個(gè)功能強(qiáng)大的工具,適用于處理集合和數(shù)據(jù)流。它提供了一種簡(jiǎn)潔而高效的方法來(lái)操作數(shù)據(jù),尤其是在處理大量數(shù)據(jù)時(shí)。這個(gè)API優(yōu)化了數(shù)據(jù)處理邏輯,使開(kāi)發(fā)者能夠以更少的代碼執(zhí)行復(fù)雜的數(shù)據(jù)轉(zhuǎn)換和聚合操作。利用Java Stream API,可以輕松實(shí)現(xiàn)數(shù)據(jù)過(guò)濾、排序、轉(zhuǎn)換及匯總,極大地提升了代碼的可讀性和可維護(hù)性。同時(shí),Stream API 的函數(shù)式編程特性有助于減少錯(cuò)誤和側(cè)效應(yīng),使得并發(fā)程序的編寫(xiě)更為安全。通過(guò)使用Java Stream API,開(kāi)發(fā)者可以寫(xiě)出更簡(jiǎn)潔、更高效、更易于維護(hù)的代碼,同時(shí)享受到函數(shù)式編程帶來(lái)的好處。
到此這篇關(guān)于Java Stream API詳解與使用示例詳解的文章就介紹到這了,更多相關(guān)Java Stream API使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
超簡(jiǎn)潔java實(shí)現(xiàn)雙色球若干注隨機(jī)號(hào)碼生成(實(shí)例代碼)
這篇文章主要介紹了超簡(jiǎn)潔java實(shí)現(xiàn)雙色球若干注隨機(jī)號(hào)碼生成(實(shí)例代碼),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-04-04
深入理解Java運(yùn)行時(shí)數(shù)據(jù)區(qū)_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要介紹了Java運(yùn)行時(shí)數(shù)據(jù)區(qū)的相關(guān)知識(shí),非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友參考下吧2017-06-06
Java基礎(chǔ)教程之獲取操作系統(tǒng)及瀏覽器信息
最近在開(kāi)發(fā)中需要從request中獲取操作系統(tǒng),瀏覽器及瀏覽器版本信息,所以下面這篇文章主要給的大家介紹了關(guān)于Java基礎(chǔ)教程之獲取操作系統(tǒng)及瀏覽器信息的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2021-10-10
Runtime.getRuntime().exec 路徑包含空格的解決
這篇文章主要介紹了Runtime.getRuntime().exec 路徑包含空格的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11
淺談什么是SpringBoot異常處理自動(dòng)配置的原理
今天給大家?guī)?lái)的是關(guān)于Java的相關(guān)知識(shí),文章圍繞著SpringBoot異常處理自動(dòng)配置展開(kāi),文中有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下2021-06-06
Java進(jìn)階教程之運(yùn)行時(shí)類型識(shí)別RTTI機(jī)制
這篇文章主要介紹了Java進(jìn)階教程之運(yùn)行時(shí)類型識(shí)別RTTI機(jī)制,在Java運(yùn)行時(shí),RTTI維護(hù)類的相關(guān)信息,比如多態(tài)(polymorphism)就是基于RTTI實(shí)現(xiàn)的,需要的朋友可以參考下2014-09-09

