Java Stream reduce()使用指南
reduce()
是 Java Stream API 中的一個終端操作,它用于將流中的元素逐個結(jié)合起來,生成一個值。換句話說,reduce()
通過對流中的元素應(yīng)用二元運(yùn)算(一個接收兩個輸入?yún)?shù)并返回一個結(jié)果的操作),將多個元素“歸約”成一個值。
1. reduce() 方法的作用
reduce()
用于從流中生成單一結(jié)果,常見的用途有:
- 計(jì)算總和、乘積
- 計(jì)算最大值、最小值
- 將字符串、對象等組合成一個結(jié)果
reduce()
操作接受兩個參數(shù):
- 一個初始值(稱為“標(biāo)識”)。
- 一個二元運(yùn)算符,通常以 lambda 表達(dá)式的形式提供。
最終結(jié)果是一個 Optional 值,表示該流的歸約結(jié)果。常用的重載形式如下:
2. reduce() 方法的三種重載形式
形式一:reduce(BinaryOperator<T> accumulator)
這個形式?jīng)]有初始值,流的第一個元素將作為初始值。返回的是 Optional<T>
,以防流為空。
Optional<Integer> sum = list.stream() .reduce((a, b) -> a + b);
形式二:reduce(T identity, BinaryOperator<T> accumulator)
這個形式有初始值 identity
,可以保證即使流為空也會有一個默認(rèn)結(jié)果。返回的是 T
。
int sum = list.stream() .reduce(0, (a, b) -> a + b);
形式三:reduce(U identity, BiFunction<U, T, U> accumulator, BinaryOperator<U> combiner)
這個形式適用于并行流操作,它可以通過兩個函數(shù)實(shí)現(xiàn)累加器和合并器的分離。通常用于并行執(zhí)行任務(wù)時(shí),按塊操作進(jìn)行合并。
int sum = list.parallelStream() .reduce(0, (partialResult, element) -> partialResult + element, // 累加器 Integer::sum); // 合并器
3. reduce() 的示例
讓我們通過幾個具體示例來理解 reduce()
的用法。
1. 計(jì)算總和
假設(shè)我們有一個整數(shù)列表,想通過 reduce()
計(jì)算所有整數(shù)的總和:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5); // 使用有初始值的 reduce int sum = numbers.stream() .reduce(0, (a, b) -> a + b); // 初始值為 0 System.out.println(sum); // 輸出:15
解釋:
reduce(0, (a, b) -> a + b)
:這里 0
是初始值,(a, b) -> a + b
是累加器,流中的每個元素與前面的計(jì)算結(jié)果累加,得到最終的總和。
2. 計(jì)算乘積
你還可以用 reduce()
計(jì)算所有元素的乘積。假設(shè)我們想要計(jì)算一個整數(shù)列表的乘積:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5); int product = numbers.stream() .reduce(1, (a, b) -> a * b); // 初始值為 1 System.out.println(product); // 輸出:120
解釋:
reduce(1, (a, b) -> a * b)
:初始值是 1(因?yàn)槌朔ǖ膯挝辉厥?1),然后通過累乘計(jì)算所有元素的乘積。
3. 字符串連接
假設(shè)我們有一組字符串,想通過 reduce()
將它們連接起來,生成一個長字符串。
List<String> words = Arrays.asList("Hello", "World", "Stream", "API"); String result = words.stream() .reduce("", (a, b) -> a + " " + b); // 初始值為空字符串 System.out.println(result); // 輸出:" Hello World Stream API"
解釋:
reduce("", (a, b) -> a + " " + b)
:初始值是空字符串 ""
,通過將每個單詞添加到之前的字符串后面,生成最終的結(jié)果。
4. 找出最大值
假設(shè)我們想找到一個整數(shù)列表中的最大值:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5); int max = numbers.stream() .reduce(Integer.MIN_VALUE, (a, b) -> a > b ? a : b); // 初始值為 Integer.MIN_VALUE System.out.println(max); // 輸出:5
解釋:
reduce(Integer.MIN_VALUE, (a, b) -> a > b ? a : b)
:初始值是 Integer.MIN_VALUE
,表示最小的可能值。通過比較流中的每個元素,最終找到最大的那個。
5. 找出最小值
類似地,我們可以用 reduce()
找到最小值:
int min = numbers.stream() .reduce(Integer.MAX_VALUE, (a, b) -> a < b ? a : b); // 初始值為 Integer.MAX_VALUE System.out.println(min); // 輸出:1
4. 無初始值的 reduce()
如果流為空,且使用無初始值的 reduce()
,返回的將是一個 Optional
對象。這是因?yàn)槿绻鳛榭?,沒有值可供“歸約”,因此結(jié)果是空的。
示例:
List<Integer> emptyList = new ArrayList<>(); Optional<Integer> result = emptyList.stream() .reduce((a, b) -> a + b); // 沒有初始值 System.out.println(result); // 輸出:Optional.empty
解釋:
因?yàn)?emptyList
是空的,沒有初始值,因此 reduce()
返回一個空的 Optional
對象,表示沒有可供“歸約”的元素。
5. 并行流中的 reduce()
在并行流中(parallelStream()
),reduce()
可以通過第三種重載方法來高效處理大數(shù)據(jù)集。它將流拆分成多個子流,并通過累加器和合并器進(jìn)行并行處理。
并行流中的示例:
int sum = numbers.parallelStream() .reduce(0, (partialResult, element) -> partialResult + element, Integer::sum); System.out.println(sum); // 輸出:15
解釋:
reduce(0, (partialResult, element) -> partialResult + element, Integer::sum)
:這里的累加器是 (partialResult, element) -> partialResult + element
,合并器是 Integer::sum
,它們幫助在并行流中將多個子流的結(jié)果合并。
6. reduce() 與其他終端操作的對比
collect()
:用于將流的元素收集到一個集合中,比如List
、Set
或Map
。forEach()
:用于遍歷流中的每個元素,進(jìn)行操作,但不返回結(jié)果。count()
:用于統(tǒng)計(jì)流中的元素?cái)?shù)量。
而 reduce()
則是將流中的所有元素“歸約”成單一的結(jié)果,它不用于收集或遍歷,而是用于生成某個聚合值。
總結(jié)
reduce()
是一個用于對流中的元素進(jìn)行聚合或“歸約”的操作。- 它將流中的多個元素通過二元運(yùn)算符逐一結(jié)合,生成一個單一結(jié)果。
- 典型用法包括求和、乘積、字符串連接、查找最大值和最小值。
- 在使用無初始值的
reduce()
時(shí),結(jié)果會是Optional
,以防流為空。 - 在并行流中,
reduce()
可以通過累加器和合并器并行處理大數(shù)據(jù)。
通過 reduce()
,你可以非常靈活地對流中的數(shù)據(jù)進(jìn)行復(fù)雜的聚合操作。
到此這篇關(guān)于Java Stream reduce()詳解的文章就介紹到這了,更多相關(guān)Java Stream reduce()內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java如何發(fā)送get請求獲取數(shù)據(jù)(附代碼)
這篇文章主要給大家介紹了關(guān)于java如何發(fā)送get請求獲取數(shù)據(jù)的相關(guān)資料,Java中的GET請求方法是HTTP協(xié)議中的一種請求方式,用于向服務(wù)器請求獲取資源,需要的朋友可以參考下2023-10-10Spring?Boot實(shí)現(xiàn)消息的發(fā)送和接收使用實(shí)戰(zhàn)指南
這篇文章主要為大家介紹了Spring?Boot實(shí)現(xiàn)消息的發(fā)送和接收使用實(shí)戰(zhàn)指南,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-06-06spring @EventListener 事件與監(jiān)聽的示例詳解
本文介紹了自定義Spring事件和監(jiān)聽器的方法,包括如何發(fā)布事件、監(jiān)聽事件以及如何處理異步事件,通過示例代碼和日志,展示了事件的順序執(zhí)行和異步處理機(jī)制,感興趣的朋友一起看看吧2025-03-03Spring boot validation校驗(yàn)方法實(shí)例
這篇文章主要給大家介紹了關(guān)于Spring boot validation校驗(yàn)方法的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-02-02SpringBoot+Mybatis使用Enum枚舉類型總是報(bào)錯No enum constant&n
這篇文章主要介紹了SpringBoot+Mybatis使用Enum枚舉類型總是報(bào)錯No enum constant XX問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-12-12SpringMvc web.xml配置實(shí)現(xiàn)原理過程解析
這篇文章主要介紹了SpringMvc web.xml配置實(shí)現(xiàn)原理過程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-08-08