import java.text.DecimalFormat;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.Arrays;
import java.util.stream.Stream;
import java.util.stream.Collectors;
class Main {
private final static DecimalFormat formatter = new DecimalFormat("0.00");
public static void main(String[] args) {
List<Item> items = Arrays.asList(
new Item("Laptop", "Electronics", 1200.0),
new Item("Mouse", "Electronics", 25.0),
new Item("Shirt", "Clothing", 30.0)
);
Map<String, List<String>> itemNamesByCategories = getItemNamesByCategories(items);
System.out.println(itemNamesByCategories);
Map<String, Double> itemTotalByCategories = getTotalByCategories(items);
System.out.println(itemTotalByCategories.entrySet().stream()
.collect(Collectors.toMap(entry -> entry.getKey(), entry -> formatter.format(entry.getValue()))));
Map<String, Map<String, Object>> itemStatisticsByCategories = getStatisticsByCategories(items);
System.out.println(itemStatisticsByCategories);
}
/**
* Exercise #1
*
* Map<String, List<String>> where key is category, value is list of uppercase item names.
*
*/
private static Map<String, List<String>> getItemNamesByCategories(List<Item> items) {
return items.stream()
.collect(Collectors.groupingBy(Item::getCategory, TreeMap::new, Collectors.mapping(item -> item.getName().toUpperCase(), Collectors.toList())));
}
/**
* Exercise #2
*
* Write code to get: Map<String, Double> where key is category, value is rounded total price (2 decimals).
*
*/
private static Map<String, Double> getTotalByCategories(List<Item> items) {
return items.stream()
.collect(Collectors.groupingBy(Item::getCategory, TreeMap::new, Collectors.collectingAndThen(Collectors.summingDouble(item -> item.getPrice()),
value -> Math.round(value * 100.0) / 100.0
)));
}
/**
* Exercise #3
*
* Get: Map<String, Map<String, Object>> with:
* - Key: Category
* - Value: Map with keys "count", "total", "average"
*
* Expected structure:
*
* {
* Electronics: {count=2, total=1225.00, avg=612.50},
* Clothing: {count=1, total=30.00, avg=30.00}
* }
*/
private static Map<String, Map<String, Object>> getStatisticsByCategories(List<Item> items) {
return items.stream()
.collect(Collectors.groupingBy(Item::getCategory, TreeMap::new, Collectors.collectingAndThen(
Collectors.toList(),
list -> {
Map<String, Object> stats = new TreeMap<>();
stats.put("count", list.size());
stats.put("total", formatter.format(list.stream().mapToDouble(Item::getPrice).sum()));
stats.put("avg", formatter.format(list.stream().mapToDouble(Item::getPrice).average().orElse(0.0)));
return stats;
}
)));
}
}
class Item {
private String name;
private String category;
private double price;
public Item(String name, String category, double price) {
this.name = name;
this.category = category;
this.price = price;
}
public String getName() { return name; }
public String getCategory() { return category; }
public double getPrice() { return price; }
}