欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java 8系列之Stream中萬(wàn)能的reduce用法說(shuō)明

 更新時(shí)間:2020年08月19日 15:38:20   作者:行云間  
這篇文章主要介紹了Java 8系列之Stream中萬(wàn)能的reduce用法說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧

reduce 操作可以實(shí)現(xiàn)從Stream中生成一個(gè)值,其生成的值不是隨意的,而是根據(jù)指定的計(jì)算模型。比如,之前提到count、min和max方法,因?yàn)槌S枚患{入標(biāo)準(zhǔn)庫(kù)中。事實(shí)上,這些方法都是reduce操作。

reduce方法有三個(gè)override的方法:

Optional<T> reduce(BinaryOperator<T> accumulator);
T reduce(T identity, BinaryOperator<T> accumulator);
<U> U reduce(U identity,BiFunction<U, ? super T, U> accumulator,BinaryOperator<U> combiner);

我們先看第一個(gè)變形,其接受一個(gè)函數(shù)接口BinaryOperator<T>,而這個(gè)接口又繼承于BiFunction<T, T, T>.在BinaryOperator接口中,又定義了兩個(gè)靜態(tài)方法minBy和maxBy。這里我們先不管這兩個(gè)靜態(tài)方法,先了解reduce的操作。

@FunctionalInterface
public interface BinaryOperator<T> extends BiFunction<T,T,T> {

 public static <T> BinaryOperator<T> minBy(Comparator<? super T> comparator) {
 Objects.requireNonNull(comparator);
 return (a, b) -> comparator.compare(a, b) <= 0 ? a : b;
 }

 public static <T> BinaryOperator<T> maxBy(Comparator<? super T> comparator) {
 Objects.requireNonNull(comparator);
 return (a, b) -> comparator.compare(a, b) >= 0 ? a : b;
 }
}

在使用時(shí),我們可以使用Lambada表達(dá)式來(lái)表示

BinaryOperator接口,可以看到reduce方法接受一個(gè)函數(shù),這個(gè)函數(shù)有兩個(gè)參數(shù),第一個(gè)參數(shù)是上次函數(shù)執(zhí)行的返回值(也稱為中間結(jié)果),第二個(gè)參數(shù)是stream中的元素,這個(gè)函數(shù)把這兩個(gè)值相加,得到的和會(huì)被賦值給下次執(zhí)行這個(gè)函數(shù)的第一個(gè)參數(shù)。要注意的是:第一次執(zhí)行的時(shí)候第一個(gè)參數(shù)的值是Stream的第一個(gè)元素,第二個(gè)參數(shù)是Stream的第二個(gè)元素。這個(gè)方法返回值類型是Optional,

Optional accResult = Stream.of(1, 2, 3, 4)
 .reduce((acc, item) -> {
  System.out.println("acc : " + acc);
  acc += item;
  System.out.println("item: " + item);
  System.out.println("acc+ : " + acc);
  System.out.println("--------");
  return acc;
 });
System.out.println("accResult: " + accResult.get());
System.out.println("--------");
// 結(jié)果打印
--------
acc : 1
item: 2
acc+ : 3
--------
acc : 3
item: 3
acc+ : 6
--------
acc : 6
item: 4
acc+ : 10
--------
accResult: 10
--------

下面來(lái)看第二個(gè)變形,與第一種變形相同的是都會(huì)接受一個(gè)BinaryOperator函數(shù)接口,不同的是其會(huì)接受一個(gè)identity參數(shù),用來(lái)指定Stream循環(huán)的初始值。如果Stream為空,就直接返回該值。另一方面,該方法不會(huì)返回Optional,因?yàn)樵摲椒ú粫?huì)出現(xiàn)null。

int accResult = Stream.of(1, 2, 3, 4)
  .reduce(0, (acc, item) -> {
  System.out.println("acc : " + acc);
  acc += item;
  System.out.println("item: " + item);
  System.out.println("acc+ : " + acc);
  System.out.println("--------");
  return acc;
  });
System.out.println("accResult: " + accResult);
System.out.println("--------");
// 結(jié)果打印
acc : 0
item: 1
acc+ : 1
--------
acc : 1
item: 2
acc+ : 3
--------
acc : 3
item: 3
acc+ : 6
--------
acc : 6
item: 4
acc+ : 10
--------
accResult: 10
--------

從打印結(jié)果可以看出,reduce前兩種變形,因?yàn)榻邮軈?shù)不同,其執(zhí)行的操作也有相應(yīng)變化:

變形1,未定義初始值,從而第一次執(zhí)行的時(shí)候第一個(gè)參數(shù)的值是Stream的第一個(gè)元素,第二個(gè)參數(shù)是Stream的第二個(gè)元素

變形2,定義了初始值,從而第一次執(zhí)行的時(shí)候第一個(gè)參數(shù)的值是初始值,第二個(gè)參數(shù)是Stream的第一個(gè)元素

對(duì)于第三種變形,我們先看各個(gè)參數(shù)的含義,第一個(gè)參數(shù)返回實(shí)例u,傳遞你要返回的U類型對(duì)象的初始化實(shí)例u,第二個(gè)參數(shù)累加器accumulator,可以使用二元?表達(dá)式(即二元lambda表達(dá)式),聲明你在u上累加你的數(shù)據(jù)來(lái)源t的邏輯,例如(u,t)->u.sum(t),此時(shí)lambda表達(dá)式的行參列表是返回實(shí)例u和遍歷的集合元素t,函數(shù)體是在u上累加t,第三個(gè)參數(shù)組合器combiner,同樣是二元?表達(dá)式,(u,t)->u。

在官方文檔上有這么一段介紹,

U result = identity;

for (T element : this stream)

result = accumulator.apply(result, element)

return result;

but is not constrained to execute sequentially.

The identity value must be an identity for the combiner function. This means that for all u, combiner(identity, u) is equal to u. Additionally, the combiner function must be compatible with the accumulator function; for all u and t, the following must hold:

combiner.apply(u, accumulator.apply(identity, t)) == accumulator.apply(u, t)

因?yàn)閞educe的變形的第一個(gè)參數(shù)類型是實(shí)際返回實(shí)例的數(shù)據(jù)類型,同時(shí)其為一個(gè)泛型也就是意味著該變形的可以返回任意類型的數(shù)據(jù)。從上面文檔介紹的字面意思解讀是第三個(gè)參數(shù)函數(shù)用來(lái)組合兩個(gè)值,而這兩個(gè)值必須與第二個(gè)函數(shù)參數(shù)相兼容,也就是說(shuō)它們所得的結(jié)果是一樣的??吹竭@里肯定有迷惑的地方,第三個(gè)參數(shù)到底是用來(lái)干嘛的?我們先看一段代碼,為了便于了解其中的緣由,并沒(méi)有使用Lambda表達(dá)式,

ArrayList<Integer> accResult_ = Stream.of(1, 2, 3, 4)
 .reduce(new ArrayList<Integer>(),
  new BiFunction<ArrayList<Integer>, Integer, ArrayList<Integer>>() {
   @Override
   public ArrayList<Integer> apply(ArrayList<Integer> acc, Integer item) {

   acc.add(item);
   System.out.println("item: " + item);
   System.out.println("acc+ : " + acc);
   System.out.println("BiFunction");
   return acc;
   }
  }, new BinaryOperator<ArrayList<Integer>>() {
   @Override
   public ArrayList<Integer> apply(ArrayList<Integer> acc, ArrayList<Integer> item) {
   System.out.println("BinaryOperator");
   acc.addAll(item);
   System.out.println("item: " + item);
   System.out.println("acc+ : " + acc);
   System.out.println("--------");
   return acc;
   }
  });
System.out.println("accResult_: " + accResult_);
// 結(jié)果打印
item: 1
acc+ : [1]
BiFunction
item: 2
acc+ : [1, 2]
BiFunction
item: 3
acc+ : [1, 2, 3]
BiFunction
item: 4
acc+ : [1, 2, 3, 4]
BiFunction
accResult_: [1, 2, 3, 4]
accResult_: 10

首先示例代碼中,傳遞給第一個(gè)參數(shù)是ArrayList,在第二個(gè)函數(shù)參數(shù)中打印了“BiFunction”,而在第三個(gè)參數(shù)接口中打印了函數(shù)接口中打印了”BinaryOperator“.可是,看打印結(jié)果,只是打印了“BiFunction”,而沒(méi)有打印”BinaryOperator“,說(shuō)明第三個(gè)函數(shù)參數(shù)病沒(méi)有執(zhí)行。這里我們知道了該變形可以返回任意類型的數(shù)據(jù)。

對(duì)于第三個(gè)函數(shù)參數(shù),為什么沒(méi)有執(zhí)行,剛開(kāi)始的時(shí)候也是沒(méi)有看懂到底是啥意思呢,而且其參數(shù)必須為返回的數(shù)據(jù)類型?看了好幾遍文檔也是一頭霧水。

在 java8 reduce方法中的第三個(gè)參數(shù)combiner有什么作用?

這里找到了答案,Stream是支持并發(fā)操作的,為了避免競(jìng)爭(zhēng),對(duì)于reduce線程都會(huì)有獨(dú)立的result,combiner的作用在于合并每個(gè)線程的result得到最終結(jié)果。

這也說(shuō)明了了第三個(gè)函數(shù)參數(shù)的數(shù)據(jù)類型必須為返回?cái)?shù)據(jù)類型了。

需要注意的是,因?yàn)榈谌齻€(gè)參數(shù)用來(lái)處理并發(fā)操作,如何處理數(shù)據(jù)的重復(fù)性,應(yīng)多做考慮,否則會(huì)出現(xiàn)重復(fù)數(shù)據(jù)!

以上這篇Java 8系列之Stream中萬(wàn)能的reduce用法說(shuō)明就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Spring Cloud Gateway + Nacos 實(shí)現(xiàn)動(dòng)態(tài)路由

    Spring Cloud Gateway + Nacos 實(shí)現(xiàn)動(dòng)態(tài)路由

    這篇文章主要介紹了Spring Cloud Gateway + Nacos 實(shí)現(xiàn)動(dòng)態(tài)路由的方法,幫助大家實(shí)現(xiàn)路由信息的自動(dòng)更新,感興趣的朋友可以了解下
    2020-10-10
  • Spring Data JPA+kkpager實(shí)現(xiàn)分頁(yè)功能實(shí)例

    Spring Data JPA+kkpager實(shí)現(xiàn)分頁(yè)功能實(shí)例

    本篇文章主要介紹了Spring Data JPA+kkpager實(shí)現(xiàn)分頁(yè)功能實(shí)例,具有一定的參考價(jià)值,有興趣的可以了解一下
    2017-06-06
  • 聊聊springboot中整合log4g2的問(wèn)題

    聊聊springboot中整合log4g2的問(wèn)題

    這篇文章主要介紹了springboot中整合log4g2的方法,自定義文件名需要在application.yml中配置,在config中配置log4g2.xml文件,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2021-11-11
  • 一文講解如何優(yōu)雅的調(diào)試jar包

    一文講解如何優(yōu)雅的調(diào)試jar包

    在現(xiàn)實(shí)開(kāi)發(fā)過(guò)程中,現(xiàn)場(chǎng)環(huán)境永遠(yuǎn)比開(kāi)發(fā)環(huán)境復(fù)雜,下面這篇文章主要給大家介紹了關(guān)于如何優(yōu)雅的調(diào)試jar包的相關(guān)資料,文中通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2022-03-03
  • Spring中的@Transactional事務(wù)失效場(chǎng)景解讀

    Spring中的@Transactional事務(wù)失效場(chǎng)景解讀

    這篇文章主要介紹了Spring中的@Transactional事務(wù)失效場(chǎng)景解讀,如果Transactional注解應(yīng)用在非public 修飾的方法上,Transactional將會(huì)失效此方法會(huì)檢查目標(biāo)方法的修飾符是否為 public,不是 public則不會(huì)獲取@Transactional 的屬性配置信息,需要的朋友可以參考下
    2023-12-12
  • ThreadPoolExecutor核心線程數(shù)和RocketMQ消費(fèi)線程調(diào)整詳解

    ThreadPoolExecutor核心線程數(shù)和RocketMQ消費(fèi)線程調(diào)整詳解

    這篇文章主要介紹了ThreadPoolExecutor核心線程數(shù)和RocketMQ消費(fèi)線程調(diào)整詳解,Rocketmq 消費(fèi)者在高峰期希望手動(dòng)減少消費(fèi)線程數(shù),通過(guò)DefaultMQPushConsumer.updateCorePoolSize方法可以調(diào)用內(nèi)部的setCorePoolSize設(shè)置多線程核心線程數(shù),需要的朋友可以參考下
    2023-10-10
  • Go?Java算法之為運(yùn)算表達(dá)式設(shè)計(jì)優(yōu)先級(jí)實(shí)例

    Go?Java算法之為運(yùn)算表達(dá)式設(shè)計(jì)優(yōu)先級(jí)實(shí)例

    這篇文章主要為大家介紹了Go?Java算法之為運(yùn)算表達(dá)式設(shè)計(jì)優(yōu)先級(jí)實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • idea如何解決maven依賴沖突

    idea如何解決maven依賴沖突

    這篇文章主要介紹了idea如何解決maven依賴沖突問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • java多線程累加計(jì)數(shù)的實(shí)現(xiàn)方法

    java多線程累加計(jì)數(shù)的實(shí)現(xiàn)方法

    在多線程協(xié)作任務(wù)中,如何計(jì)算也是很重的,這篇文章主要介紹了java多線程累加計(jì)數(shù)的實(shí)現(xiàn)方法,感興趣的朋友可以了解一下
    2021-05-05
  • Java利用Jackson序列化實(shí)現(xiàn)數(shù)據(jù)脫敏詳解

    Java利用Jackson序列化實(shí)現(xiàn)數(shù)據(jù)脫敏詳解

    在項(xiàng)目中有些敏感信息不能直接展示,比如客戶手機(jī)號(hào)、身份證、車牌號(hào)等信息,展示時(shí)均需要進(jìn)行數(shù)據(jù)脫敏,防止泄露客戶隱私。本文將利用Jackson序列化實(shí)現(xiàn)數(shù)據(jù)脫敏,需要的可以參考一下
    2023-03-03

最新評(píng)論