Home > Software design >  Iterating to a List of objects and adding to a HashMap after calculating the average
Iterating to a List of objects and adding to a HashMap after calculating the average

Time:11-11

I need to create a function

Map<Category, Double> averagePricePerCategory

that receives a List<Buildings> buildings as a parameter of objects that have:

private int price;
private String neighborhood;
private Category category;

I need to get the price for each of them, calculate the average and return a Map with their respective category and its average price. I'm really struggling to understand how I can do this.

So far I'm stuck at what to do next and how it should like.

static Map<Category, Double> averagePricePerCategory(List<Building> buildings) {
    Map<String, Double> averagePriceCategory = new HashMap<>();
    Category x = buildings.get(0).getCategory();
    if(buildings.isEmpty()){
        return new HashMap<>();
    }else{
        for(Building b: buildings){

        }
    }
    return null;
}

CodePudding user response:

If got the point of your question, using strem api you could use samething like this:

static Map<Category, Double> averagePricePerCategory(List<Building> buildings) {
        return buildings.stream().collect(Collectors.groupingBy(Building::getCategory, Collectors.averagingDouble(Building::getPrice)));
    }

You can find more esample about grouping with stream api here: https://www.baeldung.com/java-groupingby-collector

CodePudding user response:

To make a performant average solution from a list of numeric values, keep two variables : the sum of them, the count of them, then avg = sum/count

As we need to do it for each Category, we need a grouping step, an idea could be to make lists of prices for each Category, but that will be memory consuming, so we're sticking to the first idea of sum and count, for each Category

static Map<Category, Double> averagePricePerCategory(List<Building> buildings) {
    Map<Category, Double> sumPriceCategory = new HashMap<>();
    Map<Category, Integer> countPriceCategory = new HashMap<>();

    for (Building building : buildings) {
        sumPriceCategory.merge(building.getCategory(), building.getPrice(), Double::sum);
        countPriceCategory.merge(building.getCategory(), 1, Integer::sum);
    }

    Map<Category, Double> avgPriceCategory = new HashMap<>();
    for (Map.Entry<Category, Double> entry : sumPriceCategory.entrySet()) {
        avgPriceCategory.put(entry.getKey(), entry.getValue() / countPriceCategory.get(entry.getKey()));
    }
    return avgPriceCategory;
}

List<Building> buildings = List.of(
        new Building(10, new Category("house")), new Building(20, new Category("house")),
        new Building(30, new Category("house")), new Building(40, new Category("house")),
        new Building(40, new Category("school")), new Building(400, new Category("school"))
);
System.out.println(averagePricePerCategory(buildings)); // {school=220.0, house=25.0}
  • Related