Home > Blockchain >  Calculate the product total sum of each category in Map - Java
Calculate the product total sum of each category in Map - Java

Time:04-24

I have a Map and I am trying to calculate the total sum value of products for each CategoryName, then get the category where the total sum is the greatest, and display this sum.

I grouped the Map by categories, now i am struggling how i could calculate this sum, any solutions?

That's my class:

public class ProductCategories {
        private String categoryName;
        private int productId;
        private double price;

        public ProductCategories(String categoryName, int productId, double price) {
            this.categoryName = categoryName;
            this.productId = productId;
            this.price = price;
        }

        public String getCategoryName() {
            return categoryName;
        }

        public int getProductId() {
            return productId;
        }

        public double getPrice() {
        return price;
    }



        public void setCategoryName(String categoryName) {
            this.categoryName = categoryName;
        }

        public void setProductId(int productId) {
            this.productId = productId;
        }

        public void setProductId(double price) {
        this.price = price;
    }


    @Override
        public String toString() {
            return "ProductCategories{"   "Category name='"   categoryName   '\''   ", productID="   productId   ", price='"   price   '\''   '}';
        }


        private static Map<String, Integer> productIdToNameMap(List<ProductCategories> categoryList) {
            return categoryList.stream()
                    .collect(Collectors.toMap(ProductCategories::getCategoryName, ProductCategories::getProductId, (first, second) -> first   second, TreeMap::new
                    ));
        }

        private static Map<String, List<ProductCategories>> multiValueMap(List<ProductCategories> categoryList) {
            return categoryList.stream()
                    .collect(Collectors.groupingBy(ProductCategories::getCategoryName));
        }

        public static void main(String[] args) {
            List<ProductCategories> categoryList = new ArrayList<>();
            categoryList.add(new ProductCategories("The Fellowship of the Ring", 1954, 12));
            categoryList.add(new ProductCategories("The Return of the King", 1954, 12));
            categoryList.add(new ProductCategories("The Return of the King", 1955, 12));


            //System.out.println(productIdToNameMap(categoryList));
            System.out.println(multiValueMap(categoryList));
        }
}

Output:

{The Return of the King=[ProductCategories{Category name='The Return of the King', productID=1954, price='12.0'}, ProductCategories{Category name='The Return of the King', productID=1955, price='12.0'}], The Fellowship of the Ring=[ProductCategories{Category name='The Fellowship of the Ring', productID=1954, price='12.0'}]}

CodePudding user response:

I am trying to calculate the total sum value of products for each CategoryName, then get the category where the total sum is the greatest, and display this sum.

To find the maximum total price, first you need to find the total price for each category.

You can do it either by using a combination of collectors Collectors.groupingBy and Collectors.summingDouble as a downstream, or with Collectors.toMap by providing a merge function as a third argument of this collector.

And then create a stream over the values of the intermediate map and retrieve the maximum.


If you need both maximum total price and a name of category, then need to create a stream over the entry set and peek the entry with maximum value providing Map.Entry.comparingByValue() as comparator.

    private static Map.Entry<String, Double> getMaxByCategoryName(List<ProductCategories> categoryList) {
        return categoryList.stream()
            .collect(Collectors.toMap(ProductCategories::getCategoryName,
                        ProductCategories::getPrice,
                        Double::sum))
            .entrySet().stream()
            .max(Map.Entry.comparingByValue())
            .orElse(Map.entry("no data evalable", 0d));
    }

CodePudding user response:

First, the name of your method is somewhat misleading. You should think about it and change it to something more meaningful than multiValueMap.

You can create the sums for the individual categories by simply applying a downstream collector like Collectors.summingDouble:

private static Map<String, Double> multiValueMap(List<ProductCategories> categoryList) {
    return categoryList.stream()
            .collect(Collectors.groupingBy(ProductCategories::getCategoryName,
                    Collectors.summingDouble(ProductCategories::getPrice)));
}
  • Related