<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Java8函數(shù)式編程真有這么神奇?- [完結(jié)篇]不得不學(xué)的Collector與map...

          共 8802字,需瀏覽 18分鐘

           ·

          2022-06-10 11:00

          本文是java8函數(shù)式編程精講stream最后一節(jié),一般最后一節(jié)都是拔高的重頭戲。

          我會(huì)重點(diǎn)講解一下Stream中收集器Collector的主要使用方式。這也是實(shí)際編程中經(jīng)常使用到的編程技巧和語法糖。無論是從實(shí)用性還是從知識(shí)擴(kuò)展角度,掌握它的性價(jià)比都非常高。

          廢話不多說,直接進(jìn)入正題。

          收集器

          收集器(Collector)的作用為:將流中元素累積成一個(gè)結(jié)果作用于終端操作collect()上

          關(guān)于收集器,我們主要關(guān)注:

          ????collect()(操作實(shí)現(xiàn)Collector接口的集合)、

          ????Collector(接口)

          ????Collectors(工具類)

          日常開發(fā)中,我們使用最多的是預(yù)定義收集器功能(Collectors)

          它的作用主要是:

          ????將流元素規(guī)約和匯總為一個(gè)值

          ????將流元素分組

          ????將流元素分區(qū)

          Collect()方法解析

          ?????R?collect(Supplier?supplier,??????????????????????初始化結(jié)果容器
          ????????????????BiConsumer?accumulator,??????添加元素到結(jié)果容器的邏輯
          ????????????????BiConsumer?combiner);????????????????并行執(zhí)行時(shí)多個(gè)結(jié)果容器的合并方式

          我們此處介紹幾個(gè)常用的預(yù)定義收集器方法

          集合收集器

          ????@Test
          ????public?void?toList()?{
          ????????List?list?=?CartService.getCartSkuList();
          ????????List?result?=?list.stream()
          ????????????????.filter(sku?->?sku.getTotalPrice()?>?100)

          ????????????????.collect(Collectors.toList());
          ????????System.out.println(JSON.toJSONString(result,?true));
          ????}

          這個(gè)用例的目的是:選出總價(jià)大于100的商品并打印,也就是大于100的sku會(huì)被保留。

          運(yùn)行結(jié)果:

          ????[
          ????????{
          ????????????"skuCategory":"ELECTRONICS",
          ????????????"skuId":2,
          ????????????"skuName":"無人機(jī)",
          ????????????"skuPrice":1000.0,
          ????????????"totalNum":10,
          ????????????"totalPrice":1000.0
          ????????},
          ????????{
          ????????????"skuCategory":"ELECTRONICS",
          ????????????"skuId":1,
          ????????????"skuName":"VR一體機(jī)",
          ????????????"skuPrice":2100.0,
          ????????????"totalNum":10,
          ????????????"totalPrice":2100.0
          ????????},
          ????????{
          ????????????"skuCategory":"CLOTHING",
          ????????????"skuId":13,
          ????????????"skuName":"襯衫",
          ????????????"skuPrice":120.0,
          ????????????"totalNum":10,
          ????????????"totalPrice":120.0
          ????????}
          ????]

          ????Process?finished?with?exit?code?0

          集合分組

          ????@Test
          ????public?void?group()?{
          ????????List?list?=?CartService.getCartSkuList();
          ????????//?key=分組條件??value=元素集合??即Map<分組條件,結(jié)果集合>
          ????????Map>?result?=?list.stream()
          ????????????????.collect(Collectors.groupingBy(sku?->?sku.getSkuCategory()));
          ????????System.out.println(JSON.toJSONString(result,?true));
          ????}
          ?

          這個(gè)用例的目的是:根據(jù)sku類別對(duì)list進(jìn)行分組,分組結(jié)束后返回一個(gè)Map<分組條件,結(jié)果集合>,即key=分組條件 ?value=元素集合

          ?

          運(yùn)行結(jié)果:

          ????{"CLOTHING":[
          ????????????{
          ????????????????"skuCategory":"CLOTHING",
          ????????????????"skuId":4,
          ????????????????"skuName":"牛仔褲",
          ????????????????"skuPrice":60.0,
          ????????????????"totalNum":10,
          ????????????????"totalPrice":60.0
          ????????????},
          ????????????{
          ????????????????"skuCategory":"CLOTHING",
          ????????????????"skuId":13,
          ????????????????"skuName":"襯衫",
          ????????????????"skuPrice":120.0,
          ????????????????"totalNum":10,
          ????????????????"totalPrice":120.0
          ????????????}
          ????????],"BOOKS":[
          ????????????{
          ????????????????"skuCategory":"BOOKS",
          ????????????????"skuId":121,
          ????????????????"skuName":"Java編程思想",
          ????????????????"skuPrice":100.0,
          ????????????????"totalNum":10,
          ????????????????"totalPrice":100.0
          ????????????},
          ????????????{
          ????????????????"skuCategory":"BOOKS",
          ????????????????"skuId":3,
          ????????????????"skuName":"程序化廣告",
          ????????????????"skuPrice":80.0,
          ????????????????"totalNum":10,
          ????????????????"totalPrice":80.0
          ????????????}
          ????????],"ELECTRONICS":[
          ????????????{
          ????????????????"skuCategory":"ELECTRONICS",
          ????????????????"skuId":2,
          ????????????????"skuName":"無人機(jī)",
          ????????????????"skuPrice":1000.0,
          ????????????????"totalNum":10,
          ????????????????"totalPrice":1000.0
          ????????????},
          ????????????{
          ????????????????"skuCategory":"ELECTRONICS",
          ????????????????"skuId":1,
          ????????????????"skuName":"VR一體機(jī)",
          ????????????????"skuPrice":2100.0,
          ????????????????"totalNum":10,
          ????????????????"totalPrice":2100.0
          ????????????}
          ????????]
          ????}

          從運(yùn)行結(jié)果我們可以看出滿足要求。

          集合分區(qū)

          集合分區(qū)是分組的一種特例:

          ?

          分區(qū)是由一個(gè)謂詞作為分區(qū)函數(shù),分區(qū)函數(shù)返回一個(gè)boolean值最終將分區(qū)結(jié)果分為兩組,一組為boolean=true的 ? 一組為boolean=false的通俗的說也就是滿足條件的分為一組,不滿足條件的為一組

          ?
          ????@Test
          ????public?void?partition()?{
          ????????List?list?=?CartService.getCartSkuList();
          ????????Map>?partition?=?list.stream()
          ????????????????.collect(Collectors.partitioningBy(sku?->?sku.getTotalPrice()?>?100));
          ????????System.out.println(JSON.toJSONString(partition,?true));
          ????}

          運(yùn)行結(jié)果:

          ????{
          ????????false:[
          ????????????{
          ????????????????"skuCategory":"CLOTHING",
          ????????????????"skuId":4,
          ????????????????"skuName":"牛仔褲",
          ????????????????"skuPrice":60.0,
          ????????????????"totalNum":10,
          ????????????????"totalPrice":60.0
          ????????????},
          ????????????{
          ????????????????"skuCategory":"BOOKS",
          ????????????????"skuId":121,
          ????????????????"skuName":"Java編程思想",
          ????????????????"skuPrice":100.0,
          ????????????????"totalNum":10,
          ????????????????"totalPrice":100.0
          ????????????},
          ????????????{
          ????????????????"skuCategory":"BOOKS",
          ????????????????"skuId":3,
          ????????????????"skuName":"程序化廣告",
          ????????????????"skuPrice":80.0,
          ????????????????"totalNum":10,
          ????????????????"totalPrice":80.0
          ????????????}
          ????????],
          ????true:[
          ????????????{
          ????????????????"skuCategory":"ELECTRONICS",
          ????????????????"skuId":2,
          ????????????????"skuName":"無人機(jī)",
          ????????????????"skuPrice":1000.0,
          ????????????????"totalNum":10,
          ????????????????"totalPrice":1000.0
          ????????????},
          ????????????{
          ????????????????"skuCategory":"ELECTRONICS",
          ????????????????"skuId":1,
          ????????????????"skuName":"VR一體機(jī)",
          ????????????????"skuPrice":2100.0,
          ????????????????"totalNum":10,
          ????????????????"totalPrice":2100.0
          ????????????},
          ????????????{
          ????????????????"skuCategory":"CLOTHING",
          ????????????????"skuId":13,
          ????????????????"skuName":"襯衫",
          ????????????????"skuPrice":120.0,
          ????????????????"totalNum":10,
          ????????????????"totalPrice":120.0
          ????????????}
          ????????]
          ????}

          ????Process?finished?with?exit?code?0

          通過日志打印我們能夠看出,根據(jù)是否滿足斷言將集合分為兩個(gè)組。結(jié)果與分組很像,只不過key變成了true/false。

          流高級(jí)操作

          接下來是Java8函數(shù)式編程系列的最后一個(gè)章節(jié),到此我們的Stream相關(guān)的講解就暫時(shí)告一段落。

          ?

          本節(jié)中我將帶領(lǐng)讀者朋友一起學(xué)習(xí)一下Stream高級(jí)編程相關(guān)的知識(shí)。

          ?

          規(guī)約與匯總

          Stream操作中有兩個(gè)相對(duì)高階的概念,分別為規(guī)約和匯總。

          規(guī)約(reduce)

          ????將Stream流中元素轉(zhuǎn)換成一個(gè)值

          匯總(collect)

          ????將Stream流中的元素轉(zhuǎn)換成一個(gè)容器,如Map?、List?、?Set

          上文我們已經(jīng)講過了匯總操作Collect,此處我們重點(diǎn)講講規(guī)約操作(reduce)

          「對(duì)reduce的理解」

          ?

          reduce 操作可以實(shí)現(xiàn)從Stream中生成一個(gè)值,其生成的值不是隨意的,是根據(jù)指定的計(jì)算模型。

          ?
          ?

          比如,之前提到count、min和max方法,因?yàn)槌S枚患{入標(biāo)準(zhǔn)庫中。事實(shí)上,這些方法都是reduce操作。

          ?

          我們看一個(gè)案例

          ????????/**
          ????????* reduce 案例1:
          ????????*??????計(jì)算一批商品的總價(jià)格
          ????????*/
          ????????@Test
          ????????public?void?reduceTest()?{

          ????????????/**
          ????????????*?準(zhǔn)備一批訂單數(shù)據(jù)
          ????????????*/
          ????????????List?list?=?Lists.newArrayList();
          ????????????list.add(new?Order(1,?2,?15.12));
          ????????????list.add(new?Order(2,?5,?257.23));
          ????????????list.add(new?Order(3,?3,?23331.12));

          ????????????/**
          ????????????*?傳統(tǒng)方式
          ????????????*?1.?計(jì)算商品數(shù)量
          ????????????*?2.?計(jì)算消費(fèi)總金額
          ????????????*
          ????????????*?以下展示Stream的reduce方式
          ????????????*?思想:分治法
          ????????????*
          ????????????*??????U?reduce(U?identity,?????????????????????????????????初始基點(diǎn),此處就是訂單中屬性都是0
          ????????????*??????????????????BiFunction?accumulator,????計(jì)算邏輯,定義兩個(gè)元素如何進(jìn)行操作
          ????????????*??????????????????BinaryOperator?combiner);????????????????并行執(zhí)行時(shí)多個(gè)部分結(jié)果的合并方式
          ????????????*
          ????????????*/

          ????????????/**
          ????????????*?匯總商品數(shù)量和總金額
          ????????????*/
          ????????????Order?order?=?list.stream()
          ????????????????????//.parallel()?????//?并行方式
          ????????????????????.reduce(
          ????????????????????????????//?參數(shù)1:初始化值
          ????????????????????????????new?Order(0,?0,?0.0),
          ????????????????????????????//?參數(shù)2:Stream中兩個(gè)元素的計(jì)算邏輯
          ????????????????????????????(Order?order1,?Order?order2)?->?{
          ????????????????????????????????System.out.println("執(zhí)行?計(jì)算邏輯?方法?。?!");
          ????????????????????????????????//?計(jì)算兩個(gè)訂單商品數(shù)量和,消費(fèi)金額之和
          ????????????????????????????????int?productCount?=?order1.getProductCount()?+?order2.getProductCount();
          ????????????????????????????????double?totalAmount?=?order1.getTotalAmount()?+?order2.getTotalAmount();
          ????????????????????????????????//?返回計(jì)算結(jié)果
          ????????????????????????????????return?new?Order(0,?productCount,?totalAmount);
          ????????????????????????????},
          ????????????????????????????//?參數(shù)3:并行情況下,多個(gè)并行結(jié)果如何合并
          ????????????????????????????(Order?order1,?Order?order2)?->?{
          ????????????????????????????????System.out.println("執(zhí)行?合并?方法?。?!");
          ????????????????????????????????//?計(jì)算兩個(gè)訂單商品數(shù)量和,消費(fèi)金額之和
          ????????????????????????????????int?productCount?=?order1.getProductCount()?+?order2.getProductCount();
          ????????????????????????????????double?totalAmount?=?order1.getTotalAmount()?+?order2.getTotalAmount();
          ????????????????????????????????//?返回計(jì)算結(jié)果
          ????????????????????????????????return?new?Order(0,?productCount,?totalAmount);
          ????????????????????????????});
          ????????????System.out.println(JSON.toJSONString(order,?true));
          ????????}
          ????}

          運(yùn)行結(jié)果:

          ????執(zhí)行?計(jì)算邏輯?方法?。?!
          ????執(zhí)行?計(jì)算邏輯?方法?。。?br />????執(zhí)行?計(jì)算邏輯?方法?。?!
          ????{
          ????????"id":0,
          ????????"productCount":10,
          ????????"totalAmount":23603.469999999998
          ????}

          可見通過reduce邏輯,我們能夠很輕松實(shí)現(xiàn)注入復(fù)雜條件的累加,求最值等操作。

          reduce規(guī)約操作,實(shí)際上采用了分治思想,提升了編碼和執(zhí)行效率。

          更多關(guān)于reduce的解析可以參考 ? https://blog.csdn.net/weixin_41835612/article/details/83687078

          4.9 Stream特點(diǎn):

          通過上述的介紹,我們能夠總結(jié)出Stream的特點(diǎn):

          • 「無存儲(chǔ)」。stream不是一種數(shù)據(jù)結(jié)構(gòu),它只是某種數(shù)據(jù)源的一個(gè)視圖,數(shù)據(jù)源可以是一個(gè)數(shù)組,Java容器或I/O channel等。

          • 「為函數(shù)式編程而生」。對(duì)stream的任何修改都不會(huì)修改背后的數(shù)據(jù)源,比如對(duì)stream執(zhí)行過濾操作并不會(huì)刪除被過濾的元素,而是會(huì)產(chǎn)生一個(gè)不包含被過濾元素的新stream。

          • 「惰式執(zhí)行」。stream上的操作并不會(huì)立即執(zhí)行,只有等到用戶真正需要結(jié)果的時(shí)候才會(huì)執(zhí)行。

          • 「可消費(fèi)性」。stream只能被“消費(fèi)”一次,一旦遍歷過就會(huì)失效,就像容器的迭代器那樣,想要再次遍歷必須重新生成。

          更多Java8特性

          由于篇幅及筆者個(gè)人能力有限,不能將Java8的所有特性都詳細(xì)的呈現(xiàn),感興趣的同學(xué)可以自行學(xué)習(xí)。

          ????Optional

          ????接口默認(rèn)方法

          ????新的日期和時(shí)間API

          ????CompletableFuture:組合式異步編程

          ????G1垃圾回收器

          推薦閱讀

          ????《Java8實(shí)戰(zhàn)》Java8?In?Action中文版

          ????《深入理解JVM&G1?GC》

          總結(jié)

          到此,針對(duì)Java8的新特性Lambda表達(dá)式及stream流式編程的講解就告一段落,希望本系列對(duì)讀者朋友們有所幫助。

          這不是結(jié)束,這也不是開始,這是結(jié)束的開始。


          瀏覽 33
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                    <th id="afajh"><progress id="afajh"></progress></th>
                    成人做爰A片一区二区 | 成人性爱网站在线 | 国产日韩精品无码去免费专区国产 | 天堂Av在线成人电影 | 大香蕉亚洲成人 |