在循环中设置Hashmap

时间:2010-03-03 02:59:13

标签: java iteration hashmap

我有以下代码:

Map<String, ObjectType> objectMap = new HashMap<String, ObjectType>();
for (ObjectType obj : objects) {
    obj.setSomeProperty("property value");
    objectMap.put(obj.getADiffProperty(), obj);
}

似乎在循环迭代期间,某些obj属性针对不同的键而不是当前正在设置的键进行更改。上面的代码有问题吗?不知何故,对obj的引用正在被for循环回收?

此循环也在外循环中。

更新的:
我提供以下完整方法。我观察上述行为的实际位置在外部地图中定义为在Singleton类中定义的Map<String, Map<String, GlossaryTerm>> loadedTerms = new HashMap<String, Map<String, GlossaryTerm>>();

List<Audience> audiences = ContentAccess.getAudienceList();

List<GlossaryTerm> glossaryTerms = ContentAccess.getAllReplacementCIs();                            

for (Audience audience : audiences) {                   
    Map<String, GlossaryTerm> termMap = new HashMap<String, GlossaryTerm>();
    for (GlossaryTerm term : glossaryTerms) {
       String definition = term.getProductGlossary().get(audience.getName());
       if (definition != null)
           term.setDefinition(definition);
       termMap.put(term.getPhrase(), term);
   }                        
   loadedTerms.put(audience.getChannelId(), termMap);
}

5 个答案:

答案 0 :(得分:2)

  

似乎在循环迭代期间,某些obj属性针对不同的键而不是当前正在设置的键进行更改。上面的代码有问题吗?不知何故,对obj的引用正在被for循环回收?

每次循环时,obj变量将被设置为objects的迭代器的“next”元素。如果您在obj中多次看到相同的参考值,则只能是因为:

  • 参考值在集合,数组或objects给出的任何内容中真正出现过多次,或

  • setSomePropertygetADiffProperty中的某些内容或您在循环中执行的其他操作正在更新objects作为副作用,或

  • objects对象有一个错误的迭代器实现。

另一种可能性是,您所看到的是具有相同adiff值的不同对象。

再说一遍,我需要查看比您提供的简化代码段更多的源代码。

编辑 - 您提供的额外代码未显示问题。 (我认为我们可以忽略任何涉及在迭代时更新列表的理论,或者来自制定者的奇怪副作用。)

我怀疑单身人士提供的其中一个列表包含重复或其他意外情况。可能是造成问题的原因。

执行@Carl建议并使用跟踪图和/或调试器来确定Collection单例中的内容以及代码实际执行的操作。

编辑2 - 集合thingy是单例类的事实可能无关紧要。并且HashMap的内容不会随机或自发地改变。 (并且你的代码中没有任何绿色恶魔密谋让它失败。请相信我!)

你似乎有头脑猜测问题是什么,并根据这些猜测做出改变,希望他们能解决问题。 停止抱怨!这是错误的做法,可能只会让事情变得更糟。你需要做的是仔细和有条不紊地调试代码,收集你的程序实际做了什么的确凿证据,并仔细解释这些证据......而不是诉诸于某些东西随意改变事物的疯狂观念。

编辑3 - 如果我遇到你的情况,我会请团队中另一位经验丰富的Java程序员坐下来帮助我调试代码。我自己偶尔也需要这样做,而且我有10年+ Java经验和30多年的编程经验。有时你会对问题产生心理障碍,而新的思维/新方​​法就是答案。

向你的团队/老板承认你不够深入并需要帮助并不是一件可耻的事。

答案 1 :(得分:2)

我不认为你的想法正在发生,正在发生。对于每次迭代,对象引用都是它应该是的。我认为必须发生其他事情 - 属性在其他地方发生变化,或者没有你认为他们最初拥有的价值。放入一些printlns来追踪真实情况。您显示的代码无法更改错误的属性。

答案 2 :(得分:1)

我正在开始一个新的答案,因为 - 嗯,这是一个新思路,讨论主题变得相当长。

当发生变化时,你没有(我认为)说过。但是,您(可能)将相同的术语放入多个地图中,针对不同的受众。与循环变量无关 - 只是您为每个受众重复使用相同的术语列表。但是当您将该术语放入地图时,您也会更改其定义。但是,每个受众的定义(可能)都不同。所以,具体的例子:

对于观众X,术语A具有“x”的定义,对于观众Y具有“y”。您有两个观众。最初,我们遇到观众X,所以A得到定义“x”。 A会添加到地图中以供此受众群体使用。现在我们迭代到下一个受众,将A的定义更改为“y”。这会改变A随处可见的参考 - 包括在观众X的地图中。这可以解释为什么制作副本可以消除问题。这是你正在经历的事情吗?

答案 3 :(得分:0)

这可能只是一个拼写错误。您的代码段中未声明object,但您的put来电使用object.getADiffProperty()而不是obj.getADiffProperty()。这是故意的吗?

答案 4 :(得分:0)

从哪里调用代码?可能有并发问题?是否有其他线程(是webapp?)访问ContentAccess?我希望GlossaryTerm是一个简单的Dto,对吧?