Java8函數式編程之Stream高階編程
本文是Java8函數式編程的最後一個章節,到此我們的Stream相關的講解就暫時告一段落。
本文中我將帶領讀者朋友一起學習一下Stream高級編程相關的知識。
規約與彙總
Stream操作中有兩個相對高階的概念,分別爲規約和彙總。
規約(reduce)
將Stream流中元素轉換成一個值
彙總(collect)
將Stream流中的元素轉換成一個容器,如Map 、List 、 Set
上文我們已經講過了彙總操作Collect,此處我們重點講講規約操作(reduce)
對reduce的理解
reduce 操作可以實現從Stream中生成一個值,其生成的值不是隨意的,是根據指定的計算模型。
比如,之前提到count、min和max方法,因爲常用而被納入標準庫中。事實上,這些方法都是reduce操作。
我們看一個案例
/** * reduce 案例1: * 計算一批商品的總價格 */ @Test public void reduceTest() { /** * 準備一批訂單數據 */ List<Order> 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)); /** * 傳統方式 * 1. 計算商品數量 * 2. 計算消費總金額 * * 以下展示Stream的reduce方式 * 思想:分治法 * * <U> U reduce(U identity, 初始基點,此處就是訂單中屬性都是0 * BiFunction<U, ? super T, U> accumulator, 計算邏輯,定義兩個元素如何進行操作 * BinaryOperator<U> combiner); 並行執行時多個部分結果的合併方式 * */ /** * 彙總商品數量和總金額 */ Order order = list.stream() //.parallel() // 並行方式 .reduce( // 參數1:初始化值 new Order(0, 0, 0.0), // 參數2:Stream中兩個元素的計算邏輯 (Order order1, Order order2) -> { System.out.println("執行 計算邏輯 方法!!!"); // 計算兩個訂單商品數量和,消費金額之和 int productCount = order1.getProductCount() + order2.getProductCount(); double totalAmount = order1.getTotalAmount() + order2.getTotalAmount(); // 返回計算結果 return new Order(0, productCount, totalAmount); }, // 參數3:並行情況下,多個並行結果如何合併 (Order order1, Order order2) -> { System.out.println("執行 合併 方法!!!"); // 計算兩個訂單商品數量和,消費金額之和 int productCount = order1.getProductCount() + order2.getProductCount(); double totalAmount = order1.getTotalAmount() + order2.getTotalAmount(); // 返回計算結果 return new Order(0, productCount, totalAmount); }); System.out.println(JSON.toJSONString(order, true)); } }
運行結果:
執行 計算邏輯 方法!!! 執行 計算邏輯 方法!!! 執行 計算邏輯 方法!!! { "id":0, "productCount":10, "totalAmount":23603.469999999998 }
可見通過reduce邏輯,我們能夠很輕鬆實現注入複雜條件的累加,求最值等操作。
reduce規約操作,實際上採用了分治思想,提升了編碼和執行效率。
更多關於reduce的解析可以參考 https://blog.csdn.net/weixin_41835612/article/details/83687078
4.9 Stream特點:
通過上述的介紹,我們能夠總結出Stream的特點:
-
無存儲。stream不是一種數據結構,它只是某種數據源的一個視圖,數據源可以是一個數組,Java容器或I/O channel等。
-
爲函數式編程而生。對stream的任何修改都不會修改背後的數據源,比如對stream執行過濾操作並不會刪除被過濾的元素,而是會產生一個不包含被過濾元素的新stream。
-
惰式執行。stream上的操作並不會立即執行,只有等到用戶真正需要結果的時候纔會執行。
-
可消費性。stream只能被“消費”一次,一旦遍歷過就會失效,就像容器的迭代器那樣,想要再次遍歷必須重新生成。
更多Java8特性
由於篇幅及筆者個人能力有限,不能將Java8的所有特性都詳細的呈現,感興趣的同學可以自行學習。
Optional 接口默認方法 新的日期和時間API CompletableFuture:組合式異步編程 G1垃圾回收器
推薦閱讀
《Java8實戰》Java8 In Action中文版 《深入理解JVM&G1 GC》
總結
到此,針對Java8的新特性Lambda表達式及stream流式編程的講解就告一段落,希望本系列對讀者朋友們有所幫助。
版權聲明:
原創不易,洗文可恥。除非註明,本博文章均爲原創,轉載請以鏈接形式標明本文地址。