2017-08-13 26 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() 
相关问题