java-在另一个Map中创建Map的问题

yhived7q  于 2021-07-12  发布在  Java
关注(0)|答案(2)|浏览(387)

我正在尝试创建一个程序来跟踪一堆不同的字符串,并用当前用户输入的名称(另一个字符串)将它们“绑定在一起”,这意味着每个人都应该有自己的钱包。我试着用另一张Map里面的Map来做这个,但这是我大脑超载的地方。如何将每个钱包与正确的名称绑定,然后显示所有这些内容?我代码中的注解给出了一个很好的例子。到目前为止,我掌握的情况如下:

Scanner sysin = new Scanner(System.in);
    boolean firstTime = true;
    Map<String, Set<Long>> walletTracker = new HashMap<String, Set<Long>>();
    Map<String, Map<String, Set<Long>>> nameTracker = new HashMap<String, Map<String, Set<Long>>>();

    if(!firstTime) {
        /* Here it should display every entered name, wallet and time of deposit, like this:

        Jack:
            JacksWallet:
                [12345], [123456], [1234567]
            JacksOtherWallet:
                [123], [1234]
        Jonathan:
            JonsWallet:
                [12345678]
        */
    }

    for(int i = 0; i < 1;) {
        System.out.print("Enter your name: ");
        String name = sysin.nextLine();
        System.out.print("Please enter a wallet name: ");
        String wallet = sysin.nextLine();

        Set<Long> deposits = walletTracker.getOrDefault(name, new HashSet<>());
        deposits.add(System.currentTimeMillis());
        walletTracker.put(wallet, deposits);
        nameTracker.put(name, walletTracker);

        System.out.println("You successfully withdrew money from "+ wallet +". Press enter to continue...");
        firstTime = false;
        String enter = sysin.nextLine();
    }
i34xakig

i34xakig1#

我发现并注意到:
这个 if(!firstTime) {} 块应该在for循环中,以便它在每次迭代中实际打印。
你试图使用 walletTracker.getOrDefault(name, new HashSet<>()); ,但是 name 变量不是此处要使用的正确变量。你应该使用 wallet 输入变量。
这是我的“打印”代码,符合您建议的格式:

nameTracker.forEach((name, wallet) -> {
    System.out.println(name);
    wallet.forEach((walletName, dates) -> {
        System.out.printf("\t%s\n\t\t%s\n",
            walletName, Arrays.toString(dates.toArray(new Long[0])));
    });
});

除此之外,用于实际填充Map的代码是正确的。
@rzwitserloot就如何利用oop为您提供了一些好的建议,我也会推荐这些建议。

kuarbcqp

kuarbcqp2#

Set<Long> deposits = walletTracker.getOrDefault(name, new HashSet<>()); 这是回报 new HashSet<>() 如果没有Map name 但这并没有把它加到Map上。你想要的是 .computeIfAbsent ,它将只返回与 name ,但如果根本不存在,它会计算lambda,然后将其添加到Map中,然后返回:

Set<Long> deposits = walletTracker.computeIfAbsent(name, k -> new HashSet<>());

这就是“lambda”语法—您不需要编写解析为新哈希集的表达式,而是编写解析为函数的表达式,该函数在提供键时生成新哈希集(这里不需要,它等于 name 无论如何)。
java风格的策略是 Wallet 至少上课。一般来说,一旦你开始 <><>,特别是如果你有3层深度,停下来,开始写类。 那应该是个好主意Map<String, Wallet>和一个Map<String, Person>` 或者别的什么。

相关问题