Как вывести название категории средней наибольшей значении?
Есть задача которую не могу выполнить.
Это ООП с использованием коллекцией Map.
Есть в поле такие значение как: Category, Name, Price.
Входные данные:
Product p1 = new Product("Vehicle", "Kia_Rio", 5_000_000);
Product p2 = new Product("Smartphone", "Iphone 11", 300_000);
Product p3 = new Product("Smartphone", "Iphone_11_Pro", 340_000);
Product p4 = new Product("Smartphone", "Iphone_12", 400_000);
Product p5 = new Product("Vehicle", "Toyota_Prius", 3_750_000);
Product p6 = new Product("Laptop", "MacBook_Pro", 650_00000);
Product p7 = new Product("Shoes", "Crocks", 25_0000000);
Product p8 = new Product("Shoes", "Nike", 35_0000000);
P.S. Вот среднее значение каждой категории:
Vehicle = 4375000
Laptop = 65000000
Shoes = 300000000
Smartphone = 346666
Задача: Вывести название категории средней наибольшей значении.
Мой неполный код:
Set<Map.Entry<String, List<Product>>> entries = categoryConsist.entrySet();
int total = 0;
String name = "";
for (Map.Entry<String, List<Product>> entry : entries) {
int nums = 0;
for (int i = 0; i < entry.getValue().size(); i++) {
nums += entry.getValue().get(i).getPrice();
}
nums /= entry.getValue().size();
if (nums >= total) {
total = nums;
}
}
System.out.println("->" + total);
}
}
В целом выводит корректные цифры, то что нужно. Но задача состоит в том что нужно вывести
Category. Для этого нужно использоватьStringно что именно записать- не знаю. Должно выйтиShoes.
Ответы (2 шт):
с stream-api довольно красиво получается
List<Product> products = List.of(p1, p2, ... , p8);
Map<String, Double> collect = products.stream()
.collect(Collectors.groupingBy(
Product::getCategory,
Collectors.averagingInt(Product::getPrice)
));
Просто при обнаружении очередного максимума обновляйте значение name. Также следует заметить, что при нестрогом условии if (nums >= total) будет запоминаться последняя категория:
Set<Map.Entry<String, List<Product>>> entries = categoryConsist.entrySet();
String
int maxAvg = 0;
String maxCat = null;
for (Map.Entry<String, List<Product>> e : entries) {
int total = 0;
for (Product p : e.getValue()) {
total += p.getPrice();
}
int avg = total / p.getValue().size();
if (avg > maxAvg) {
maxAvg = avg;
maxCat = e.getValue();
}
}
System.out.println(maxCat + " -> " + maxAvg);
Или же с использованием Stream API:
- вычислить средние значения цен для каждого списка товаров по категории
- найти максимум
Map.Entry<String, Integer> max = categoryConsist.entrySet()
.stream() // Stream<Map.Entry<String, List<Product>>>
.map(e -> Map.entry(
e.getKey(),
e.getValue().stream().mapToInt(Product::getPrice).sum()
/ e.getValue().size()
)) // Stream<Map.Entry<String, Integer>>
.collect(Collectors.maxBy(Map.Entry.comparingByValue())) // Optional
.orElse(null);
System.out.println(max.getKey() + " -> " + max.getValue());
Также средние значения можно вычислить, используя IntStream::average:
// ...
.map(e -> Map.entry(
e.getKey(),
(int) e.getValue().stream().mapToInt(Product::getPrice).average().orElse(0.0)
)) // Stream<Map.Entry<String, Integer>>
// ...