【问题标题】:Updating a Map更新地图
【发布时间】:2010-11-07 09:26:19
【问题描述】:

我有一张这样的地图:

private Map<String, List<List<String>>> someMap;
private List<List<String>> someList1;
private List<String> someList2;

....一些初始化..... ....一些列表人口....

那我有,

if(someMap.get(someKey) == null){
     someList1.add(someList2);
     someMap.put(someKey, someList1);
} else {
     someMap.get(someKey).add(someList2);
}

请注意,列表在添加到地图后会变得清晰,然后会被填充。

例如,我有两个带有一些值的键“Apple”和“Orange”。循环之后,我只得到橙色。前一个键被覆盖!!!

编辑:在循环的每次迭代中,都会填充一个列表。循环结束,它被添加到地图中,添加后,列表被清除()。

有什么建议吗?谢谢。

代码: http://pastebin.com/m2712e04 [根据要求.. 所以请不要怪我发帖..]

【问题讨论】:

  • 仅供参考:标题中不需要[JAVA],这就是我们有标签的原因
  • 我认为您需要包含已省略的位。我怀疑您混淆了键和值,但代码或您的问题中没有足够的信息来确定。
  • 在循环的每次迭代中,都会填充列表。循环结束,它被添加到地图中,添加列表后获得 clear()。
  • 你能发布更多代码吗?现在提出问题的方式,循环和列表在循环后被清除,太模糊了。循环从哪里开始,在哪里结束,哪些列表被清除等等。
  • 我对代码做了一些修改来说明我的观点。见这里:pastebin.com/pastebin.php?diff=m5a414bfb 但我可以建议(没有责备的意思!)你有一个经验丰富的编码器指导你吗?

标签: java collections


【解决方案1】:

根据您对 Lucero 问题的评论:

你是否一遍又一遍地重用同一个 List 实例,即做

 someList1.add(someList2);
 someMap.put(someKey, someList1);
 someList1.clear()
 someList1.add(stuff)
 someMap.put(someOtherKey, someList1);

这是行不通的,因为 someList1.clear() 将清除 someMap 内的列表。您每次都需要创建一个新的 List 实例:

 someList1.add(someList2);
 someMap.put(someKey, someList1);
 someList1 = new List<...>();
 someList1.add(stuff)
 someMap.put(someOtherKey, someList1);

【讨论】:

  • 我对列表及其值没有任何问题。问题在于地图及其键。当我添加第二个键时,旧键消失了!
  • @Milly:这很难相信,至少对于您提供的 sn-ps。你能发布整个方法吗?
  • 我猜你确实在地图上出现了 Clear()。或类似的东西。无论如何,如果您想获得更少的猜测答案,请发布一个完整的示例来重现该问题。
【解决方案2】:

通读您的代码:

你所描述的真的不应该发生。您真的应该使用调试器并逐行检查这行代码是否真的在做您认为它正在做的事情(ln 57):

clientCode = account.getClientId().getClientCode();

很可能是在您到达第二行之前触发了异常,或者有意外的重复数据等。

另外,我之前所说的仍然有效。在 ln 158,而不是这样做:

reportDataSubList.clear();

reportDataSubList = new ArrayList<String>();

在循环顶部还有很多不必要的初始化。


关于您的评论:

在循环的每次迭代中,列出 被填充。循环结束,它 被添加到地图和添加后 列表变得清晰()

我很惊讶这并没有破坏任何东西。地图中的所有列表都应该是空的。


如果你不这样做

List a = new ArrayList();

但是做

a.clear();

那么很清楚为什么列表是空的。您的所有条目都具有相同的参考。

通过声明

List a = new ArrayList();

您正在创建一个 List 对象的新实例,您对该对象所做的任何操作都不会影响您已经创建的内容。

【讨论】:

  • +1 看了代码,完全同意这个分析。没有任何地方——在发布的代码中肯定没有——正在创建reportDataSublist;无处创建reportDataList;甚至无处创建报告数据。每次都必须重新创建 reportDataList 和 reportDataSublist,否则您将清除已存在于 reportData 中的列表。 @Milly,您还需要将代码重构为更小的例程 - 这样会更容易查看和修复此类问题。
  • 我确实遵循了您的建议。但正如我之前所说,它不应该删除密钥。当我在 Eclipse 中调试它时,我可以看到它添加了一个新的 clientCode“apple”,然后它添加了“orange”。添加“orange”后,“apple”消失。
  • 关于列表的初始化,即使它被清除了,它应该具有相同列表集的所有键,因为当我清除并重新更新时,它会用新的列表更新所有列表值。
  • 是的,我同意。列表的初始化不会影响映射中保存的键。您确定至少有两个不同的键吗?
【解决方案3】:

我怀疑您是否想一遍又一遍地添加相同的列表。您需要为每个新键创建新的列表实例。

编辑:您的 someKey 变量是否发生了变化?您是否使用调试器单步执行代码并查看发生了什么?

编辑:更像这样:

// store the current payment info
reportDataSubList = new ArrayList<String>();
reportDataSubList.add(clientCode);
//...                                   
reportDataList = reportData.get(clientCode);
if(reportDataList == null){
    reportDataList = new ArrayList<List<String>>();
    reportData.put(clientCode, reportDataList);
}
reportDataList.add(reportDataSubList);

但我不确定您使用的数据结构是否适合这项任务。恕我直言,适当的实体对象甚至 XML 都将是击球手。

【讨论】:

  • 请注意,列表在添加到地图后会变得清晰,然后会被填充。 [已编辑]
  • 您存储的是列表引用,而不是内容。尝试创建新列表。
  • 或者使用来自 commons-collections 或 google-collections 的多图。
猜你喜欢
  • 1970-01-01
  • 2022-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-24
相关资源
最近更新 更多