Multiply and sum items of 2 lists using stream in Java

Viewed 188

I have 2 lists. One that I get the values of my database and others that I get as input. I have to multiply the value of productQuantity (HerdList) by proporcionValue (HerdCompositionList) that matches the primary key (productCode, ageRangeCode) and sum the values.

Below is the code with the for loop. How do I do it with streams?

Herd (Input)
    int productCode;
    int ageRangeCode;
    int productQuantity;

HerdComposition (DB)
    Integer productCode;
    Integer ageRangeCode;
    BigDecimal proporcionValue;

for (Herd informedItem : prodution.getHerdList()) {
    for (HerdComposition herdItem : HerdCompositionList) {
        if (herdItem.getProductCode() == informedItem.getProductCode() 
            && herdItem.getAgeRangeCode() == informedItem.getAgeRangeCode()) {
            totalHerd = totalHerd
                .add(herdItem.getProporcionValue()
                    .multiply(new BigDecimal(informedItem.getProductQuantity())));
        }
    }
}
1 Answers

Since you've mentioned the primary key as (productCode, ageRangeCode), you can create a quantity lookup map from the input list:

Map<List<?>, Integer> productQuantityLookUp = herdList.stream()
        .collect(Collectors.toMap(
                h -> Arrays.asList(h.getProductCode(), h.getAgeRangeCode()),
                Herd::getProductQuantity));

further, iterate over the database list and reduce it to get the total

BigDecimal totalHerd = herdCompositionList.stream()
        .map(hc -> new BigDecimal(productQuantityLookUp
                .getOrDefault(Arrays.asList(hc.getProductCode(), hc.getAgeRangeCode()), 0))
                .multiply(hc.getProporcionValue()))
        .reduce(BigDecimal.ZERO, BigDecimal::add);

One of the benefits of using this approach (not specifically stream), would be that your complexity would reduce from O(N*M) to O(N+M) for M times O(1) lookup of the intermediate map.

Related