成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

使用JAVA8 stream中三個(gè)參數(shù)的reduce方法對(duì)List進(jìn)行分組統(tǒng)計(jì)

崔曉明 / 1968人閱讀

摘要:背景平時(shí)在編寫前端代碼時(shí),習(xí)慣使用來編寫野生的提供來一套完整的對(duì)對(duì)象等進(jìn)行操作,這其中就包括和,即分組和聚合不知道該怎么翻譯合適。使用這些野生的能夠極大的提高我本人編寫代碼的效率。

背景

平時(shí)在編寫前端代碼時(shí),習(xí)慣使用lodash來編寫‘野生’的JavaScript;

lodash提供來一套完整的API對(duì)JS對(duì)象(Array,Object,Collection等)進(jìn)行操作,這其中就包括_.groupBy 和 _.reduce,即分組和"聚合"(reduce不知道該怎么翻譯合適)。

使用這些‘野生’的API能夠極大的提高我本人編寫JS代碼的效率。而JAVA8開始支持stream和lambda表達(dá)式,這些和lodash的API有很多類似的功能。因此我在熟悉lodash的前提下嘗試使用JAVA8的新特性減少冗余代碼的編寫。

需求

在開發(fā)后端某功能接口的過程中,需要對(duì)一個(gè)從數(shù)據(jù)庫中取出的數(shù)據(jù)List進(jìn)行按照ID進(jìn)行聚合統(tǒng)計(jì)

JAVA8 reduce API
API個(gè)人理解
   U reduce(U u,BiFunction accumulator,BinaryOperator combiner)
  #第一個(gè)參數(shù)返回實(shí)例u,傳遞你要返回的U類型對(duì)象的初始化實(shí)例u

  #第二個(gè)參數(shù)累加器accumulator,可以使用二元?表達(dá)式(即二元lambda表達(dá)式),聲明你在u上累加你的數(shù)據(jù)來源t的邏輯
  #例如(u,t)->u.sum(t),此時(shí)lambda表達(dá)式的行參列表是返回實(shí)例u和遍歷的集合元素t,函數(shù)體是在u上累加t

  #第三個(gè)參數(shù)組合器combiner,同樣是二元?表達(dá)式,(u,t)->u
  #lambda表達(dá)式行參列表同樣是(u,t),函數(shù)體返回的類型則要和第一個(gè)參數(shù)的類型保持一致
偽代碼
  #1.聲明一個(gè)返回結(jié)果U
  #2.對(duì)List進(jìn)行遍歷,在U和每個(gè)T實(shí)例上應(yīng)用一個(gè)累加器進(jìn)行累加操作
  #3.返回最終結(jié)果U
  U result = identity;
  for (T element : this stream)
      result = accumulator.apply(result, element)
  return result;
數(shù)據(jù)準(zhǔn)備
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

講了那么多廢話,這個(gè)才是最直接的

代碼執(zhí)行大意

對(duì) List 按照name分組統(tǒng)計(jì)得到 List

ReduceTest.java
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{
        List fooList = 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);
            });
    }
    /*
    輸出結(jié)果
    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
    */
}
Foo.java
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 List bazList;

    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();
    }
}
Baz.java
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

等下次有空補(bǔ)上不使用stream().reduce 實(shí)現(xiàn)同樣操作的比較繁瑣的代碼,啦啦啦啦啦~~~

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/66548.html

相關(guān)文章

  • Java8特性④Stream收集數(shù)據(jù)

    摘要:多級(jí)分組的為鍵,類型所對(duì)應(yīng)的集合為值一級(jí)分類為的,二級(jí)分類為的按子集收集數(shù)據(jù)的為鍵,類型所對(duì)應(yīng)的集合的為值分區(qū)分區(qū)是分組的特殊情況由一個(gè)謂詞返回一個(gè)布爾值的函數(shù)作為分類函數(shù),它稱分區(qū)函數(shù)。 收集器可以簡潔而靈活地定義collect用來生成結(jié)果集合的標(biāo)準(zhǔn)。更具體地說,對(duì)流調(diào)用 collect 方法將對(duì)流中的元素觸發(fā)一個(gè)歸約操作(由Collector來參數(shù)化)。一般來說,Collector...

    daryl 評(píng)論0 收藏0
  • 簡潔方便集合處理——Java 8 stream

    摘要:打印結(jié)果結(jié)果按照年齡從小到大進(jìn)行排序。打印結(jié)果果然,前兩個(gè)人都被去除了,只剩下最老的葫蘆娃爺爺。比如檢測有沒有來自巴黎的用戶。可以根據(jù)用戶所在城市進(jìn)行分組結(jié)果是一個(gè),為不重復(fù)的城市名,為屬于該城市的用戶列表。 背景 java 8已經(jīng)發(fā)行好幾年了,前段時(shí)間java 12也已經(jīng)問世,但平時(shí)的工作中,很多項(xiàng)目的環(huán)境還停留在java1.7中。而且java8的很多新特性都是革命性的,比如各種集合...

    godiscoder 評(píng)論0 收藏0
  • Java8實(shí)戰(zhàn)》-第六章讀書筆記(用流收集數(shù)據(jù)-01)

    摘要:收集器用作高級(jí)歸約剛剛的結(jié)論又引出了優(yōu)秀的函數(shù)式設(shè)計(jì)的另一個(gè)好處更易復(fù)合和重用。更具體地說,對(duì)流調(diào)用方法將對(duì)流中的元素觸發(fā)一個(gè)歸約操作由來參數(shù)化。另一個(gè)常見的返回單個(gè)值的歸約操作是對(duì)流中對(duì)象的一個(gè)數(shù)值字段求和。 用流收集數(shù)據(jù) 我們?cè)谇耙徽轮袑W(xué)到,流可以用類似于數(shù)據(jù)庫的操作幫助你處理集合。你可以把Java 8的流看作花哨又懶惰的數(shù)據(jù)集迭代器。它們支持兩種類型的操作:中間操作(如 filt...

    EscapedDog 評(píng)論0 收藏0
  • Java8流特性和Lambda表達(dá)式

    摘要:表達(dá)式體現(xiàn)了函數(shù)式編程的思想,即一個(gè)函數(shù)亦可以作為另一個(gè)函數(shù)參數(shù)和返回值,使用了函數(shù)作參數(shù)返回值的函數(shù)被稱為高階函數(shù)。對(duì)流對(duì)象進(jìn)行及早求值,返回值不在是一個(gè)對(duì)象。 Java8主要的改變是為集合框架增加了流的概念,提高了集合的抽象層次。相比于舊有框架直接操作數(shù)據(jù)的內(nèi)部處理方式,流+高階函數(shù)的外部處理方式對(duì)數(shù)據(jù)封裝更好。同時(shí)流的概念使得對(duì)并發(fā)編程支持更強(qiáng)。 在語法上Java8提供了Lamb...

    gaara 評(píng)論0 收藏0
  • Java8創(chuàng)建Stream四種方式以及 Stream 間操作

    摘要:一創(chuàng)建里流的四種方式第一種通過得方法串行流或者方法并行流創(chuàng)建。終止操作時(shí)一次性全部處理,稱為延遲加載篩選切片過濾中建操作。終止操作只有執(zhí)行終止操作才會(huì)執(zhí)行全部。即延遲加載結(jié)果中建操作。截?cái)嗔?,使其元素不超過給定數(shù)量。返回流中最大值。 Stream api **Stream api 是java8 中提供的對(duì)集合處理的api , 對(duì)數(shù)據(jù)進(jìn)行一系列的中間操作,元數(shù)據(jù)不會(huì)發(fā)生改變 ...

    0xE7A38A 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<