[英]Map<> in Map<> as value -> How to create object from the Map<> where value is another Map<>?
这里的任务是练习 Maps & Collections。
我们有 2 个类,其属性在括号中
第一个 Class:客户端(字符串名称、字符串姓氏、Integer 年龄、BigDecimal 现金)
下面是 Main 中的随机客户端列表
List<Client> clients = List.of(
new Client("Ola", "Chrzaszcz", 34, new BigDecimal("200")),
new Client("Ala", "Kowalsky", 24, new BigDecimal("4000")),
new Client("Olaf", "Chrzaszcz", 19, new BigDecimal("3999")),
new Client("Piotr", "Nowak", 21, new BigDecimal("2099")),
new Client("Ola", "Szwed", 45, new BigDecimal("3000"))
);
第 2 个 Class:产品(字符串名称、枚举类别、BigDecimal 价格)
List<Product> products = List.of(
new Product("Szynka", Category.A, new BigDecimal(29)),
new Product("Ser", Category.B, new BigDecimal(22)),
new Product("Chleb", Category.C, new BigDecimal(6)),
new Product("Maslo", Category.D, new BigDecimal(4)),
new Product("Kielbasa", Category.A, new BigDecimal(25)),
new Product("Jajka", Category.A, new BigDecimal(8)),
new Product("Szynka", Category.C, new BigDecimal(25))
);
GOAL -> EXPECTED RESULTS : in class Main create the instance of the class Shopping where attribute is a Map with <key: Client, value: Map<Product, Integer> and fill it with random data // Integer - how many products were bought
问题:
我做了什么-> 当前行为:
代码
public class Shopping {
private Map<Client, Map<Product,Integer>> quantitiesOfProductsBoughtByClient;
代码
Map<Client, Map<Product,Integer>> s1 = new HashMap<>();
s1.put(clients.indexOf(0), new Map(products.indexOf(1),5) );
List<Shopping> productsBoughtByClient = List.of(
new Map<Client, Map<Product,Integer>>(clients.indexOf(0), new Map<>(products.indexOf(0),5) ),
);
顺便说一句,我试图找到类似的问题,但没有找到,
这是一个作为起点的示例,其中有一个方法randomProductMap
接受产品列表,打乱该列表,获取随机数量的产品并生成带有随机产品数量的 map。 注意:我使用 lombok 来保存一些代码行,如果不需要,将其删除。
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.function.Function;
import java.util.stream.Collectors;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
public class Test {
public static void main(String[] args) {
List<Client> clients = List.of(
new Client("Ola", "Chrzaszcz", 34, new BigDecimal("200")),
new Client("Ala", "Kowalsky", 24, new BigDecimal("4000")),
new Client("Olaf", "Chrzaszcz", 19, new BigDecimal("3999")),
new Client("Piotr", "Nowak", 21, new BigDecimal("2099")),
new Client("Ola", "Szwed", 45, new BigDecimal("3000"))
);
List<Product> products = List.of(
new Product("Szynka", Category.A, new BigDecimal(29)),
new Product("Ser", Category.B, new BigDecimal(22)),
new Product("Chleb", Category.C, new BigDecimal(6)),
new Product("Maslo", Category.D, new BigDecimal(4)),
new Product("Kielbasa", Category.A, new BigDecimal(25)),
new Product("Jajka", Category.A, new BigDecimal(8)),
new Product("Szynka", Category.C, new BigDecimal(25))
);
Map<Client,Map<Product,Integer>> myMap =
clients.stream().collect(Collectors.toMap(
Function.identity(), c -> randomProductMap(products)));
Shopping sh = new Shopping(myMap);
sh.getQuantitiesOfProductsBoughtByClient()
.forEach((client, prodMap) -> {
System.out.println(client.getName() + " " + client.getLastName() + " bought below products");
prodMap.forEach((key,value) -> {
System.out.println("\t" + value + " x " + key.getName());
});
//Edited
BigDecimal total = prodMap.entrySet().stream()
.map(e -> e.getKey().getPrice().multiply(BigDecimal.valueOf(e.getValue())))
.reduce(BigDecimal.ZERO, (p,q)-> p.add(q), BigDecimal::add);
System.out.println("and spent total amount of: " + total);
//Edited
});
}
public static Map<Product,Integer> randomProductMap(List<Product> products){
List<Product> copy = new ArrayList<>(products);
Collections.shuffle(copy);
Random r = new Random();
List<Product> randomSizeList = copy.subList(0, r.nextInt(products.size()) + 1);
return randomSizeList.stream()
.collect(Collectors.toMap(Function.identity(), p -> r.nextInt(10)+1));
}
@Getter
@Setter
@AllArgsConstructor
@ToString
public static class Client {
String name;
String lastName;
Integer age;
BigDecimal cash;
}
@Getter
@Setter
@AllArgsConstructor
@ToString
public static class Product {
String name;
Enum category;
BigDecimal Price;
}
public static enum Category {
A, B, C, D;
}
@Getter
@Setter
@AllArgsConstructor
@ToString
public static class Shopping{
private Map<Client, Map<Product,Integer>> quantitiesOfProductsBoughtByClient;
}
}
已编辑
public Client clientWithMostExpShoping() {
return quantitiesOfProductsBoughtByClient.entrySet()
.stream()
.collect(Collectors.toMap(
Map.Entry::getKey,
entry -> entry.getValue().entrySet().stream()
.map(prodMap -> prodMap.getKey().getPrice().multiply(BigDecimal.valueOf(prodMap.getValue())))
.reduce(BigDecimal.ZERO, (prod1,prod2)-> prod1.add(prod2), BigDecimal::add)
)).entrySet().stream()
.max(Comparator.comparing(Map.Entry::getValue))
.get().getKey();
}
上面的方法应该给你花费最多的客户。 简要总结那里发生了什么:迭代quantitiesOfProductsBoughtByClient
quantityOfProductsBoughtByClient 收集到 map 保持客户为关键,并将每个产品的价格乘以数量和总和,最后通过迭代得到的 map使用Stream.max
。
虽然以上将按要求返回客户,但您不会获得其他信息,例如他到底花了多少钱。 因此,我建议您将该方法的返回值更改为Map.Entry<Client, BigDecimal>
以获得客户和总支出。 为此,只需省略最后一个.getKey();
...
.max(Comparator.comparing(Map.Entry::getValue))
.get();
甚至更简单,只需将 Map<Client, BigDecimal>客户端返回到总支出 map并将客户端的确定与最高、最低、平均或其他任何内容留给方法的调用者:
public Map<Client, BigDecimal> totalSpendingsByClient() {
return quantitiesOfProductsBoughtByClient.entrySet()
.stream()
.collect(Collectors.toMap(
Map.Entry::getKey,
entry -> entry.getValue().entrySet().stream()
.map(prodMap -> prodMap.getKey().getPrice().multiply(BigDecimal.valueOf(prodMap.getValue())))
.reduce(BigDecimal.ZERO, (prod1,prod2)-> prod1.add(prod2), BigDecimal::add)
));
}
然后,您可以使用最大或最小支出来获取客户,例如:
Map<Client, BigDecimal> clientsTotal = totalSpendingsByClient();
Client cliWithMaxTotal = clientsTotal.entrySet().stream().max(Comparator.comparing(Map.Entry::getValue)).get().getKey();
Client cliWithMinTotal = //the same as above just change max to min
已解决,非常感谢帮助 //s1 - 新 map 创建
Map<Client, Map<Product,Integer>> customersWithTheirShopping = new HashMap<>();
//将值添加到 map
customersWithTheirShopping.put(clients.get(0),Map.of(products.get(0),new Integer(5)));
customersWithTheirShopping.put(clients.get(1),Map.of(products.get(1),6));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.