简体   繁体   中英

Iterating to a List of objects and adding to a HashMap after calculating the average

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;
}

If I got the point of your question correct, using stream api you could use something 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 examples about grouping with stream api here: https://www.baeldung.com/java-groupingby-collector

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}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM