当前位置: 首页 > 知识库问答 >
问题:

映射中的映射作为值->如何从映射创建对象,其中值是另一个映射?

潘嘉佑
2023-03-14

下面是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"))
);

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

目标->预期结果:在类Main中,创建类Shopping的实例,其中属性是具有 的映射,并用随机数据//integer-购买了多少产品

    null
    null
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) ),
        );

共有1个答案

景岳
2023-03-14

这里有一个示例作为起点,其中有一个randomProductMap方法,它接受一个产品列表,洗牌这个列表,获取随机数量的产品,并生成一个带有随机数量产品的映射。注意:我使用了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();                            
 }

上面的方法应该会给你花得最多的客户。简单总结一下这方面的工作:迭代映射QuantiesofProductsBourightByClientcollect以映射,将客户端作为键,并将每个产品的价格与数量相乘,并将其加到总数,最后通过使用Stream.max迭代结果映射,得到花费最多的客户端。

...
.max(Comparator.comparing(Map.Entry::getValue))
             .get();
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     
       
 类似资料:
  • 假设我有一组字符串和一个散列函数(或任何单边函数)和一个测试函数。我想用Java8流创建一个从输入字符串到通过测试函数的哈希值的映射。我的问题是如何在中编写? 看来老的for循环是最简洁的解决方案。

  • 我有以下数据结构: <代码>地图 我想从这个复杂的 Map 对象中提取它的值(它本身是另一个字符串 Map)。我目前正在这样做: 上面的实现给了我一个新的Map对象,由于外部循环,它正在迭代。似乎我错过了什么。 如何从复杂的 Map 对象中提取内部 Map 对象? 编辑: 回应AlexWien的评论 原始数据结构: 原始数据结构背后的原因是为一对id(ID1和ID2)存储一个值。ID1和ID2可以

  • 我有一个对象,我正试图映射到。现在这个有一个名为的枚举,其中包含一些值。我想使用将它们映射到中的其他枚举值。以下是我到目前为止的代码: 当我尝试编译它时,我得到了错误:

  • 我有我创建的地图的地图 我尝试在第二个映射中迭代键的值。 所以它可以是这样的: key1->keya->value1 -------->键->值2 -------->键->值4 -------->KeyC->value1 我想继续多久就继续多久。 因此,我有,并尝试使用名为的值变量和增量计数器if来循环中的所有值 我不知道如何获得。我试着这样做 但这给了我信笺。 如果我执行,它会给出我想要的正确值

  • 卡桑德拉表列: Java实体: 当执行从表列“pickuploc”中选择查询时,并没有完全映射到实体中定义的picupLocal属性。 这是我得到的回应: 使用Spring数据卡桑德拉1.5.8