Search code examples
javacollectionslambdacycle

How calculate summ Object.getItem() from List<Object> best practic?


I have List with models

List<CallDetailFull> callDetails;//for example 50 items

It is model

public class CallDetailFull {
    private @Getter @Setter double dataUsage;
    private @Getter @Setter BigDecimal charge;
}

I need get total summ of dataUsage and total summ charge

I can make this

BigDecimal totalCharge = BigDecimal.ZERO;
                    int totaldataUsage = 0;
                    for(CallDetailFull item: callDetails){
                        totalCharge.add(item.getCharge());
                        totaldataUsage += item.getDataUsage();
                    }

But I know there is a way to solve this problem through Collections.summ() or Something like this.

Or the best solution is to add a calculation method in the model itself?

Or lambda.....

that will be the best practice and how to do it?


Solution

  • First of all, BigDecimal is an immutable class and it’s add method returns a new value that you must not drop. Further, using += on an int variable hides the fact that you have a loss of precision due to the conversion of double values to int:

    BigDecimal totalCharge = BigDecimal.ZERO;
    double totaldataUsage = 0;
    for(CallDetailFull item: callDetails){
        totalCharge = totalCharge.add(item.getCharge());
        totaldataUsage += item.getDataUsage();
    }
    

    After fixing that, your loop is a good solution and other solutions won’t improve that, especially as you are talking about 50 elements only.

    If you really want a stream solution, you can use:

    double totaldataUsage=callDetails.stream().mapToDouble(CallDetailFull::getDataUsage).sum();
    BigDecimal totalCharge = callDetails.stream().map(CallDetailFull::getCharge)
       .reduce(BigDecimal::add).orElse(BigDecimal.ZERO);