2017-08-13 68 views
1

我有一個用例需要在這個對象中總結不同的域名,所以我這樣編碼,我可以把它放在一個流中嗎?在一個java流lambda函數中總結不同的值

​​
+1

'流>的(DynamoSalesAggregateSummaryRecord :: getUnits,...)flatMapToInt(F - 。 > records.stream()。mapToInt(f))。sum()' – shmosel

回答

1

java.util.stream.IntStream.sum()是終端操作。
終端操作後,您不能調用另一個流任務。

如果您的集合中沒有太多元素,那麼GhostCat解決方案就沒有問題。
如果不是這種情況,爲避免在records集合上迭代5次,應該使用另一種方法。

您可以使用流來做到這一點,但我不確定您會獲得可讀性,因爲您應該編寫自己的代碼來計算聚合。

一個典型的循環在這方面似乎罰款:

int totalUnits = 0; 
int totalReturns = 0; 
... 
for (DynamoSalesAggregateSummaryRecord record : records){ 

    totalUnits += record.getUnits(); 
    totalReturns += record.getReturns(); 
    ... 
} 
+0

是的,我首先寫了這個,但我覺得我可以使用流來最小化代碼... –

+0

一些用例與流非常相關,它不太明顯。 – davidxxx

5

老實說,我不會這麼做。相反:擺脫擺在首位的重複代碼:寫一個小幫手調用:

return records.stream().mapToInt(accessorMethod).sum(); 

(您通過訪問該方法)。

然後你可以去:

int totals = fetch(DynamoSalesAggregateSummaryRecord::getUnits) + fetch(DynamoSalesAggregateSummaryRecord::getReturns) + ... 

但除此之外, - 它實際上並不清楚你打算在這裏做什麼。上面的例子假設你將構建所有條目的「總計」總和。如果情況並非如此 - 而且你想要「不同的」款項,我的建議是放棄使用mapToInt()。而是這樣做:

class SumHelper { 
    private int unitTotals = 0; 
    private int returnTotals = 0; 
    ... 

    public add(DynamoSalesAggregateSummaryRecord record) { 
    unitTotals += record.getUnits(); 
    ... 

使用,如:

SumHelper helper = new SumHelper; 
    records.forEach(r -> helper.add(r)); 

換句話說:你要調用一個記錄多個不同的方法;打造不同款項。你不能這樣做與流 - 作爲一個操作創建多個結果。所以你需要一些其他種「存儲」來跟蹤不同的結果。

2

另一種方法是創建一個單獨的方法getTotalSum無論是在DynamoSalesAggregateSummaryRecord類或(更好) - 外部輔助。該方法概括了所有必需的一個DynamoSalesAggregateSummaryRecord實例的領域,那麼就概括:

int totalSum = 
records.stream() 
     .mapToInt(DynamoSalesAggregateSummaryRecord::getTotalSum).sum()