在map中具有最高开销(bigdecimal)的客户机,其中value也是< map>

vshtjzan  于 2021-06-29  发布在  Java
关注(0)|答案(1)|浏览(296)

这里的任务是练习Map和收藏。
我们有两个类,其属性在括号中
第一类:客户机(字符串名称、字符串姓氏、整数年龄、bigdecimal现金)
下面是主目录中随机客户端的列表

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"))
)
;

第二类:产品(字符串名称、枚举类别、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))
);

根据这两个列表创建新Map(关键字:person,value:map<product,已售出产品的数量)

//s1 - new map creation

 Map<Client, Map<Product,Integer>> customersWithTheirShopping = new HashMap<>();

//向Map添加值

customersWithTheirShopping.put(clients.get(0), Map.of(products.get(0),5));
customersWithTheirShopping.put(clients.get(1), Map.of(products.get(1),6));
customersWithTheirShopping.put(clients.get(2), Map.of(products.get(6),16));
customersWithTheirShopping.put(clients.get(3), Map.of(products.get(5),11));
customersWithTheirShopping.put(clients.get(4), Map.of(products.get(4),5));
customersWithTheirShopping.put(clients.get(4), Map.of(products.get(3),6));
customersWithTheirShopping.put(clients.get(2), Map.of(products.get(2),8));
customersWithTheirShopping.put(clients.get(4), Map.of(products.get(1),9));

目标->预期结果:使用stream创建方法,返回花费最高的客户(价格x数量)
问题:
怎么做?如何得到Map本身的价值?!
由于这是Map,并且密钥(客户机)是唯一的,所以我们不能期望在客户机类的示例中重复,对吗(使用此Map结构)?这意味着每个顾客只可以订购一次,对吗?
我所做的->当前行为:
公共客户端Withmostexpshopping(){

return quantitiesOfProductsBoughtByClient
            .entrySet()
            .stream()
            .max(Comparator.comparing(p -> p.getValue().entrySet().stream().max(
                    Comparator.comparing(x -> x.getKey().getPrice().multiply(BigDecimal.valueOf(x.getValue()))))))
};

//顺便说一句,不幸的是没有发现类似的情况

8xiog9wr

8xiog9wr1#

是的,当前在您的代码中创建乘积和整数的不可变Map,因此您不能为客户机添加新产品。此外,还可以覆盖客户机的Map项,例如,索引为4的客户机具有 Map.of(products.get(1),9) 作为值,因为它是最后一个并覆盖以前的所有赋值
如果希望每个客户机有多个产品,可以重构为:

customersWithTheirShopping.put(clients.get(0), new HashMap<>(Map.of(products.get(0), 5)));
        customersWithTheirShopping.put(clients.get(1), new HashMap<>(Map.of(products.get(1), 6)));
        customersWithTheirShopping.put(clients.get(2), new HashMap<>(Map.of(products.get(6), 16)));
        customersWithTheirShopping.put(clients.get(3), new HashMap<>(Map.of(products.get(5), 11)));
        customersWithTheirShopping.put(clients.get(4), new HashMap<>(Map.of(products.get(4), 5)));
        customersWithTheirShopping.get(clients.get(4)).put(products.get(3), 6);
        customersWithTheirShopping.get(clients.get(2)).put(products.get(2), 8);
        customersWithTheirShopping.get(clients.get(4)).put(products.get(1), 9);

然后可以使用流来获得正确的客户机

Client clientWithMostExpense = customersWithTheirShopping
                .entrySet()
                .stream()
                .max(
                        // check all clients and compare their mostExpensiveProducts
                        Comparator.comparing(
                        client -> {
                            Map.Entry<Product, Integer> mostExpensiveProductForClient = client.getValue().entrySet()
                                    .stream().max(
                                            //Find most expensive product of all for client
                                            Comparator.comparing(product ->
                                                    product.getKey().getPrice().multiply(BigDecimal.valueOf(product.getValue())))
                                    ).get();
                            // return the full price of the most expensive product for comparison
                            return mostExpensiveProductForClient.getKey().getPrice().multiply(BigDecimal.valueOf(mostExpensiveProductForClient.getValue()));
                        }
                )).get().getKey();

另一个解决方案是将quantity和product重构为一个新的类,称为boughtproduct或类似的类,在这个类中您可以计算出它的价格

public class BoughtProduct {
        Product product;
        Integer quantity;

        public BoughtProduct(Product product, Integer quantity) {
            this.quantity = quantity;
            this.product = product;
        }

        public Integer getQuantity() {
            return quantity;
        }

        public void setQuantity(Integer quantity) {
            this.quantity = quantity;
        }

        public Product getProduct() {
            return product;
        }

        public void setProduct(Product product) {
            this.product = product;
        }

        public BigDecimal getTotalPrice(){
            return this.product.getPrice().multiply(BigDecimal.valueOf(quantity));
        }
    }

然后可以使用列表而不是Map:

Map<Client, List<BoughtProduct>> customersWithTheirShopping = new HashMap<>();
        customersWithTheirShopping.put(clients.get(0), new ArrayList<>(List.of(new BoughtProduct(products.get(0), 5))));
        customersWithTheirShopping.put(clients.get(1), new ArrayList<>(List.of(new BoughtProduct(products.get(1), 6))));
        customersWithTheirShopping.put(clients.get(2), new ArrayList<>(List.of(new BoughtProduct(products.get(6), 16))));
        customersWithTheirShopping.put(clients.get(3), new ArrayList<>(List.of(new BoughtProduct(products.get(5), 11))));
        customersWithTheirShopping.put(clients.get(4), new ArrayList<>(List.of(new BoughtProduct(products.get(4), 5))));
        customersWithTheirShopping.get(clients.get(4)).add(new BoughtProduct((products.get(3)), 6)); //could use a check whether product exists, then you could increase quantity
        customersWithTheirShopping.get(clients.get(2)).add(new BoughtProduct(products.get(2),8));
        customersWithTheirShopping.get(clients.get(4)).add(new BoughtProduct(products.get(1),9));

使流的可读性更强:

Client clientWithMostExpense = customersWithTheirShopping
                .entrySet()
                .stream()
                .max(
                        // check all clients and compare their mostExpensive BoughtProduct in their list
                        Comparator.comparing(
                                //For each client get their most expensive product
                                client -> client.getValue()
                                        .stream().max(Comparator.comparing(BoughtProduct::getTotalPrice)).get()
                                        .getTotalPrice()
                        )).get().getKey();

相关问题