0

I am trying to get a quantity count of products from a list of sales. So what I have is:

public class sale {

    public String productId;
    .
    .//other sale variables
    .
    public int amountSold;
}

The current way I have done it is based on this answer of integers: how to merge more than one hashmaps also sum the values of same key in java

So, right now im traversing a list of sale objects, and for every sale object, check the hasmap if an entry for that product exists, if it does not make one, if it does add how much of the product was sold in current sale to it.

 HashMap<String,Integer> productSaleHash = new HashMap<>();
 saleList.forEach(sale -> {
     productSaleHash.merge(sale.getProductId(), sale.getAmountSold(), Integer::sum);
 });

which works, but then i have to convert the hashmap into an arraylist, and add sale details into each entry because i also want to send other sale variales such as productName, not just the id and salecount. Therefore I am trying to find a more efficient way to do this.

This is what im trying to do, i create a new DTO object called productCount, and instead of integers im storing the object in the hasmap.

public class productCount {

        public String productId;
        public String productName;
        public int amountSold;
    } 

HashMap<String,ProductCount> productSaleHash = new HashMap<>();
    saleList.forEach(sale -> {
        productSaleHash.merge(sale.getProductId(), sale.getAmountSold(), "add old amountSold with amount from sale" );
    });
Oirampok
  • 569
  • 5
  • 23

1 Answers1

2

Let's boost the ProductCount class with the constructor and the method:

public class ProductCount {
    public String productId;
    public String productName;
    public int amountSold;
    
    ProductCount(ProductCount sale) {
         this.productId = sale.productId;
         this.amountSold = sale.amountSold;
         /* other initializations */
    }
    
    public ProductCount addAmountSoldFrom(ProductCount other) {
        this.amountSold += other.amountSold;
        return this;
    }
} 

Now the saleList can be traversed like:

HashMap<String, ProductCount> productSaleHash = new HashMap<>();
saleList.forEach(sale ->
    productSaleHash.merge(sale.productId, new ProductCount(sale), ProductCount::addAmountSoldFrom);
);
  • This works, thank you. Although I think creating a new object instead of updating a variable in an object like this goes against the very core principle of OOP. I need to find a way to access the object. – Oirampok May 18 '21 at 19:06
  • @Oirampok you can also use a lambda expression instead of a method reference and modify the object created inside the `merge` method: `(oldCount, newCount) -> { newCount.amountSold += oldCount.amountSold; return newCount; }` – Aleksandr Baklanov May 19 '21 at 05:22