摘要:背景平時在編寫前端代碼時,習慣使用來編寫野生的提供來一套完整的對對象等進行操作,這其中就包括和,即分組和聚合不知道該怎么翻譯合適。使用這些野生的能夠極大的提高我本人編寫代碼的效率。
背景
需求平時在編寫前端代碼時,習慣使用lodash來編寫‘野生’的JavaScript;
lodash提供來一套完整的API對JS對象(Array,Object,Collection等)進行操作,這其中就包括_.groupBy 和 _.reduce,即分組和"聚合"(reduce不知道該怎么翻譯合適)。
使用這些‘野生’的API能夠極大的提高我本人編寫JS代碼的效率。而JAVA8開始支持stream和lambda表達式,這些和lodash的API有很多類似的功能。因此我在熟悉lodash的前提下嘗試使用JAVA8的新特性減少冗余代碼的編寫。
JAVA8 reduce API在開發后端某功能接口的過程中,需要對一個從數據庫中取出的數據List
進行按照ID進行聚合統計
API個人理解數據準備U reduce(U u,BiFunction accumulator,BinaryOperator combiner) #第一個參數返回實例u,傳遞你要返回的U類型對象的初始化實例u #第二個參數累加器accumulator,可以使用二元?表達式(即二元lambda表達式),聲明你在u上累加你的數據來源t的邏輯 #例如(u,t)->u.sum(t),此時lambda表達式的行參列表是返回實例u和遍歷的集合元素t,函數體是在u上累加t #第三個參數組合器combiner,同樣是二元?表達式,(u,t)->u #lambda表達式行參列表同樣是(u,t),函數體返回的類型則要和第一個參數的類型保持一致偽代碼#1.聲明一個返回結果U #2.對List進行遍歷,在U和每個T實例上應用一個累加器進行累加操作 #3.返回最終結果U U result = identity; for (T element : this stream) result = accumulator.apply(result, element) return result;
var source = [ {"name": "A","type": "san","typeValue": 1.0,"count": 2}, {"name": "A","type": "nas","typeValue": 13.0,"count": 1}, {"name": "B","type": "san","typeValue": 112.0,"count": 3}, {"name": "C","type": "san","typeValue": 43.0,"count": 5}, {"name": "B","type": "nas","typeValue": 77.0,"count": 7} ]; var target = [ { "name": "A", "count": 3, "totalTypeValue": 14.0, "bazList": [ { "type": "san", "typeValue": 1.0 }, { "type": "nas" "typeValue": 13.0 } ] }, { "name": "B", "count": 10, "totalTypeValue": 189.0, "bazList": [ { "type": "san", "typeValue": 112.0 }, { "type": "nas" "typeValue": 77.0 } ] }, { "name": "C", "count": 5, "totalTypeValue": 43.0, "bazList": [ { "type": "san", "typeValue": 43.0 } ] } ];Code
講了那么多廢話,這個才是最直接的
代碼執行大意ReduceTest.java對 List
按照name分組統計得到 List
import com.google.common.collect.Lists; import Bar; import Foo; import java.util.List; import java.util.stream.Collectors; public class ReduceTest { public static void main(String[] args) throws Exception{ ListFoo.javafooList = Lists.newArrayList( new Foo("A","san",1.0,2), new Foo("A","nas",13.0,1), new Foo("B","san",112.0,3), new Foo("C","san",43.0,5), new Foo("B","nas",77.0,7) ); List barList = Lists.newArrayList(); fooList .stream() .collect(Collectors.groupingBy(Foo::getName,Collectors.toList())) .forEach((name,fooListByName)->{ Bar bar = new Bar(); bar = fooListByName .stream() .reduce(bar,(u,t)->u.sum(t),(u,t)->u); System.out.println(bar.toString()); barList.add(bar); }); } /* 輸出結果 name:A count:3 totalTypeValue:14.0 bazList: type:san typeValue:1.0 type:nas typeValue:13.0 name:B count:10 totalTypeValue:189.0 bazList: type:san typeValue:112.0 type:nas typeValue:77.0 name:C count:5 totalTypeValue:43.0 bazList: type:san typeValue:43.0 */ }
public class Foo{ private String name; private String type; private Double typeValue; private Integer count; public Foo(String name, String type, Double typeValue, Integer count) { this.name = name; this.type = type; this.typeValue = typeValue; this.count = count; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getType() { return type; } public void setType(String type) { this.type = type; } public Double getTypeValue() { return typeValue; } public void setTypeValue(Double typeValue) { this.typeValue = typeValue; } public Integer getCount() { return count; } public void setCount(Integer count) { this.count = count; } }Bar.java
import com.google.common.collect.Lists; import java.util.List; public class Bar{ private String name; private Integer count; private Double totalTypeValue; private ListBaz.javabazList; public Bar() { this.name = null; this.count = 0; this.totalTypeValue = 0.0; this.bazList = Lists.newArrayList(); } public Bar sum(Foo foo){ if(name == null){ this.name = foo.getName(); } this.count += foo.getCount(); this.totalTypeValue += foo.getTypeValue(); this.bazList.add(new Baz(foo.getType(),foo.getTypeValue())); return this; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getCount() { return count; } public void setCount(Integer count) { this.count = count; } @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append("name:").append(this.name).append(System.lineSeparator()); sb.append("count:").append(this.count).append(System.lineSeparator()); sb.append("totalTypeValue:").append(this.totalTypeValue).append(System.lineSeparator()); sb.append("bazList:").append(System.lineSeparator()); this.bazList.forEach(baz->{ sb.append(" ").append("type:").append(baz.getType()).append(System.lineSeparator()); sb.append(" ").append("typeValue:").append(baz.getTypeValue()).append(System.lineSeparator()); }); return sb.toString(); } }
public class Baz{ private String type; private Double typeValue; public Baz(String type, Double typeValue) { this.type = type; this.typeValue = typeValue; } public String getType() { return type; } public void setType(String type) { this.type = type; } public Double getTypeValue() { return typeValue; } public void setTypeValue(Double typeValue) { this.typeValue = typeValue; } }PS
等下次有空補上不使用stream().reduce 實現同樣操作的比較繁瑣的代碼,啦啦啦啦啦~~~
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/66548.html
摘要:多級分組的為鍵,類型所對應的集合為值一級分類為的,二級分類為的按子集收集數據的為鍵,類型所對應的集合的為值分區分區是分組的特殊情況由一個謂詞返回一個布爾值的函數作為分類函數,它稱分區函數。 收集器可以簡潔而靈活地定義collect用來生成結果集合的標準。更具體地說,對流調用 collect 方法將對流中的元素觸發一個歸約操作(由Collector來參數化)。一般來說,Collector...
摘要:打印結果結果按照年齡從小到大進行排序。打印結果果然,前兩個人都被去除了,只剩下最老的葫蘆娃爺爺。比如檢測有沒有來自巴黎的用戶。可以根據用戶所在城市進行分組結果是一個,為不重復的城市名,為屬于該城市的用戶列表。 背景 java 8已經發行好幾年了,前段時間java 12也已經問世,但平時的工作中,很多項目的環境還停留在java1.7中。而且java8的很多新特性都是革命性的,比如各種集合...
摘要:收集器用作高級歸約剛剛的結論又引出了優秀的函數式設計的另一個好處更易復合和重用。更具體地說,對流調用方法將對流中的元素觸發一個歸約操作由來參數化。另一個常見的返回單個值的歸約操作是對流中對象的一個數值字段求和。 用流收集數據 我們在前一章中學到,流可以用類似于數據庫的操作幫助你處理集合。你可以把Java 8的流看作花哨又懶惰的數據集迭代器。它們支持兩種類型的操作:中間操作(如 filt...
摘要:表達式體現了函數式編程的思想,即一個函數亦可以作為另一個函數參數和返回值,使用了函數作參數返回值的函數被稱為高階函數。對流對象進行及早求值,返回值不在是一個對象。 Java8主要的改變是為集合框架增加了流的概念,提高了集合的抽象層次。相比于舊有框架直接操作數據的內部處理方式,流+高階函數的外部處理方式對數據封裝更好。同時流的概念使得對并發編程支持更強。 在語法上Java8提供了Lamb...
摘要:一創建里流的四種方式第一種通過得方法串行流或者方法并行流創建。終止操作時一次性全部處理,稱為延遲加載篩選切片過濾中建操作。終止操作只有執行終止操作才會執行全部。即延遲加載結果中建操作。截斷流,使其元素不超過給定數量。返回流中最大值。 Stream api **Stream api 是java8 中提供的對集合處理的api , 對數據進行一系列的中間操作,元數據不會發生改變 ...
閱讀 2511·2021-09-26 10:18
閱讀 3386·2021-09-22 10:02
閱讀 3183·2019-08-30 15:44
閱讀 3326·2019-08-30 15:44
閱讀 1831·2019-08-29 15:25
閱讀 2572·2019-08-26 14:04
閱讀 2035·2019-08-26 12:15
閱讀 2437·2019-08-26 11:43