Search code examples
javalistjava-8java-stream

How to Sum up the attribute values of objects in a list having particular IDs and assign it to another object using Streams


My classes.

class MyLoan {
    private Long loanId;
    private BigDecimal loanAmount;
    private BigDecimal totalPaid;
    ....
}
class Customer {
    private Long loanId;
    private List<MyLoan> myLoan;
}

I want to iterate over the myLoan from a Customer and calculate the totalPaid amount.

My logic is "If loanId is 23491L or 23492L, then add the loanAmount of those two loanId's and set the value in the totalPaid amount of loanId 23490L".totalPaid amount is always showing as zero with my logic below.

And want to use Java 8 streams, but unable to write multiple conditions when using streams.

BigDecimal spreadAmount;
for (MyLoan myloan: customer.getMyLoan()) {
    if (myloan.getLoanId() == 23491L || myloan.getLoanId() == 23492L) {
        spreadAmount = spreadAmount.add(myloan.getLoanAmount());
    }
    if (myloan.getLoanId() == 23490L) {
        myloan.setTotalPaid(spreadAmount);
    }
}

Solution

  • The totalPaid field is not modified because your MyLoan instance with id 23490L is encountered before the other two.

    You should first filter for the MyLoan instance with id 23490L, and then, if this is present, set the totalPaid field by summing the loanAmount of the MyLoan instances with id 23491L and 23492L.

    This is a possible stream implementation:

    myLoan.stream()
        .filter(loan -> loan.getLoanId() == 23490L)
        .findFirst()
        .ifPresent(ml -> ml.setTotalPaid(myLoan.stream()
                .filter(loan -> loan.getLoanId() == 23491L || loan.getLoanId() == 23492L)
                .map(MyLoan::getLoanAmount)
                .reduce(BigDecimal.valueOf(0), BigDecimal::add)));