开发者

Setting Hashmap in a loop

I have the following code:

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

It seems like during loop iteration some of the obj property changes for different keys than the one currently being set. Is there a problem with the above code? Somehow the reference to obj is being recycled by the for loop?

Also this loop is in an outer loop as well.

Update:

I am providing the full method below. The actual place where I am observing the behavior described above is in the outer map defined as Map<String, Map<String, GlossaryTerm>> loadedTerms = new HashMap<String, Map<String, GlossaryTerm>>(); defined in a Singleton class.

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

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

for (Audience audience : audiences) {                   
    Map<String, GlossaryTerm> termMap = new HashMap<String, GlossaryTerm&g开发者_运维问答t;();
    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);
}


I don't think what you think is happening, is happening. The object reference is what it's supposed to be, for each iteration. I think something else must be happening - that the properties are changing elsewhere, or don't have the values you think they have initially. Put in some printlns to track down what's really going on. The code you've shown can't be changing the wrong properties.


It seems like during loop iteration some of the obj property changes for different keys than the one currently being set. Is there a problem with the above code? Somehow the reference to obj is being recycled by the for loop?

The obj variable will be set to the "next" element of the iterator for objects each time around the loop. If you see the same reference value in obj more than once it can only be because:

  • the reference value genuinely appears more than once in collection, array or whatever given by objects, or

  • something in setSomeProperty or getADiffProperty or something else you are doing in the loop is updating objects as a side-effect, or

  • the objects object has a buggy iterator implementation.

Another possibility is that what you are seeing is different objects with the same adiff values.

To say anything more, I'd need to see more source-code than the simplified snippet you have provided.

EDIT - the extra code you provided has not revealed the problem. (I think we can dismiss any theories involving updating the lists while they are being iterated, or strange side-effects from the setters.)

My suspicion is that one of those lists that the singleton is providing contains duplicates or something else unexpected. It could be that is what is causing your problem.

Do what @Carl suggests and use traceprints and/or a debugger to figure out what is in the Collection singleton and what your code is actually doing.

EDIT 2 - The fact that the collection thingy is a singleton class is probably irrelevant. And the contents of a HashMap DO NOT change randomly or spontaneously. (And there are no little green demons in your code that conspire to make it fail. Trust me on this!)

You seem to have the mindsight of guessing what the problem is and making changes based on those guesses in the hope that they will fix the problem. STOP GUESSING! That is the wrong approach, and will probably only make things worse. What you need to do is debug the code carefully and methodically, gathering hard evidence of what your program is actually doing, and interpreting that evidence carefully ... without resorting to crazy notions that something is changing things randomly.

EDIT 3 - If I was in your situation, I would ask another experienced Java programmer in the team to sit down with me and help me debug the code. I still occasionally need to do this myself, and I've had 10 years+ Java experience and 30+ years programming experience. Sometimes you get a mental block on a problem, and a fresh mind / fresh approach is the answer.

It is not a shameful thing to admit to your team / boss that you are out of your depth and need help.


I'm starting a new answer because - well, it's a new thought here, and the discussion thread was getting rather long.

You haven't (I think) said when the changes happen. But you are (potentially) putting the same term into multiple maps, for different audiences. Nothing to do with the loop variable - just that you are repeatedly using the same list of terms, for each audience. But when you put the term into a map, you also change its definition. But the definition is (potentially) different for each audience. So, concrete example:

Term A has the definition of "x" for audience X, and "y" for audience Y. You have both audiences. Initially, we encounter audience X, so A gets definition "x". A gets added to the map for this audience. Now we iterate to the next audience, and change the definition for A to "y". This changes A everywhere you have a reference to it - including in the map for audience X. This would explain why making a copy eliminates the problem. Is this what you are experiencing?


This might be just a typo error. There is no object declared in your snippet, but your put call uses object.getADiffProperty() rather than obj.getADiffProperty(). Is that intentional?


From where the code is called? May be there are concurrent issues? Are there other threads (is it a webapp?) accessing ContentAccess? And I hope GlossaryTerm is a simple Dto, right?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜