2017-02-22 2 views
5

Ich habe eine List<LedgerEntry> ledgerEntries und ich muss die Summe von creditAmount und debitAmount berechnen.Streams: Berechnen Sie die Differenz der Summen auf einmal

class LedgerEntry{ 
private BigDecimal creditAmount; 
private BigDecimal debitAmount; 

//getters and setters 
} 

ich umgesetzt haben, dies als,

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); 

Das sieht aus wie ich das über List zweimal laufen bin. Gibt es eine Möglichkeit, dies auf einmal zu erledigen, ohne die Liste zweimal durchspielen zu müssen?

Antwort

4

Sie können die einzelnen Beträge in map subtrahieren und dann sum sie reduce

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

Danke. Das war schnell. Auf die gleiche Anmerkung, was ist, wenn ich die zwei Werte getrennt brauche (dh: creditTotal und debitTotal getrennt). – Krishan

+1

@ Krishan Willkommen. Können Sie näher erläutern, was Sie meinen, indem Sie die beiden Werte getrennt benötigen? – CKing

+0

Genau wie in meiner Frage, wenn ich creditTotal und debotTotal Werte separat brauche, um später verwendet zu werden, kann ich das tun, indem ich nur einmal durch die Liste iteriere? Mit stream() zweimal für die gleiche Liste scheint zweimal über die Liste zu iterieren? Oder ist das nicht der Fall und der Compiler zaubert etwas, um das Streaming zu optimieren? – Krishan

6

nur reduzieren sie auf:

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

* creditTotalSubtract (debotTotal); * ...... – CKing

+1

@CKing Das war ein Tippfehler ... Fixed. – manouti

+1

Downvote eingefahren. +1 – CKing

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

* creditTotal_subtract (debotTotal); ..... * – CKing

+1

Fest, danke – kamehl23

+0

Leider ist dies jetzt eine völlig neue Antwort von Ihrem ersten Versuch. Mehr von einem Repost als von einem Fix. – CKing

2

Hier verwendet, ist meine Lösung:

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

Ich bekomme die Differenz zwischen jedem Debit-Debit-Paar und füge sie zusammen unter reduce.

Verwandte Themen