2017-02-22 111 views
5

我有一个List<LedgerEntry> ledgerEntries,我需要计算creditAmount和debitAmount的总和。流:一次计算总计的差异

class LedgerEntry{ 
private BigDecimal creditAmount; 
private BigDecimal debitAmount; 

//getters and setters 
} 

我已经实现了本作,

BigDecimal creditTotal = ledgeredEntries.stream().map(p ->p.getCreditAmount()). 
reduce(BigDecimal.ZERO, BigDecimal::add); 
BigDecimal debitTotal = ledgeredEntries.stream().map(p ->p.getDebitAmount()). 
reduce(BigDecimal.ZERO, BigDecimal::add); 
BigDecimal sumCreditDebit = creditTotal.subtract(debitTotal); 

这看起来像我遍历List两次。有没有办法一次完成这项工作,而无需两次蒸汽清单?

回答

4

您可以减去单项金额在map,然后sum他们使用reduce

ledgerEntries.stream() 
    .map(e->e.getCreditAmount().subtract(e.getDebitAmount()) 
    .reduce(0,BigDecimal::add); 
+0

谢谢。那很快。 在同一张纸条上,如果我分别需要两个值(即:creditTotal和debitTotal分开)会怎么样。 – Krishan

+1

@Krishan欢迎您。你能否分别需要两个值来详细说明你的意思? – CKing

+0

就像在我的问题,如果我需要creditTotal和debitTotal值分别以后使用,我可以通过迭代通过列表一次吗?对同一个列表使用stream()两次似乎就是遍历列表两次?或者情况并非如此,编译器会优化流式传输? – Krishan

6

只是将其降低到:

BigDecimal sumCreditDebit = ledgeredEntries.stream().map(p -> p.getCreditAmount() 
     .subtract(p.getDebitAmount())) 
     .reduce(BigDecimal.ZERO, BigDecimal::add); 
+1

* creditTotal.subtract(debitTotal); * ...... – CKing

+1

@CKing这是一个错字......固定。 – manouti

+1

Downvote缩回。 +1 – CKing

3
BigDecimal result = ledgeredEntries.stream().map(p -> p.getCreditAmount().subtract(p.getDebitAmount())) 
      .reduce(BigDecimal.ZERO, BigDecimal::add); 
+1

* creditTotal.subtract(debitTotal); ..... * – CKing

+1

已修复,谢谢 – kamehl23

+0

不幸的是,这是您最初尝试的一个全新的答案。更多的重新发布而不是修复。 – CKing

2

这里是我的解决方案:

BigDecimal result = array.stream().reduce(BigDecimal.ZERO, 
      (bigDecimal, ledgerEntry) -> bigDecimal.add(ledgerEntry.getCreditAmount()).subtract(ledgerEntry.getDebitAmount()), 
      BigDecimal::add); 

我得到每个信用借记对之间的差异,并使用reduce将它们加在一起。