views:

142

answers:

3
+1  Q: 

Updating a Map

I have a map like this:

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

....Some initialization..... ....Some list population....

Then I have,

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

Note that the list gets clear after adding to the map and gets populated afterward.

For instance, I have two keys "Apple" and "Orange" with some values. After the loop, I get only Orange. The previous key gets overridden!!!

EDIT: In every iteration of a loop, a list gets populated. End of the loop, it gets added to the map and after adding, the list gets clear().

Any advice? Thanks.

CODE: http://pastebin.com/m2712e04 [On request.. so please don't blame me for posting it..]

+1  A: 

I doubt that you want to add the same lists over and over again. You need to create new list instances for each new key.

Edit: Does your someKey variable change at all? Have you used the debugger to step into the code and look what is happening?

Edit: Do it more like this:

// 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);

But I'm not sure that the data structure you're using is well suited for the task. Proper entity objects or even XML would be a batter match IMHO.

Lucero
Note that the list gets clear after adding to the map and gets populated afterward. [Edited]
You're storing the list references, not the contents. Try creating new lists.
Steve Reed
Or use a multimap from commons-collections or google-collections.
Steve Reed
PROBLEM SOLVED. THANKS.
+2  A: 

Based on your comment to Lucero's question:

Are you reusing the same List instance over and over again, i.e. doing

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

That will not work, as someList1.clear() will clear the list inside someMap. You need to create a fresh List instance every time:

 someList1.add(someList2);
 someMap.put(someKey, someList1);
 someList1 = new List<...>();
 someList1.add(stuff)
 someMap.put(someOtherKey, someList1);
sleske
I have no problem with the lists and their values. The problem is with the Map and its keys. When I add the second key, the old key gets vanished!
@ Milly: That's hard to believe, at least with the snippets you've provided. Can you post the entire method?
Cambium
My guess is that you do come Clear() on the map. Or something like that. Anyways, post a full sample reproducing the issue if you want to get less guessing answers.
Lucero
http://pastebin.com/m2712e04
+1  A: 

Read through your code:

What you are describing really should not be happening. You should really use a debugger and step through the lines and check if this line of code is actually doing what you are thinking it's doing (ln 57):

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

It's very likely an exception triggered before you reached your second row, or there are unexpected duplicate data, etc.

Also, what I said earlier is still valid. At ln 158, instead of doing:

reportDataSubList.clear();

Do

reportDataSubList = new ArrayList<String>();

You also have a lot of unnecessary initialization at the top of your loop.


Regarding your comment:

In every iteration of a loop, list gets populated. End of the loop, it gets added to the map and after adding the list gets clear()

I'm surprised this is not breaking anything. All your lists in your map should be empty.


If you aren't doing

List a = new ArrayList();

but doing

a.clear();

then it's clear why the list is empty. All your entries are of the same reference.

By declaring

List a = new ArrayList();

you are creating a new instance of List object, and whatever you do to this object will not affect what you have already created.

Cambium
+1 After looking at the code, I agree completely with this analysis. There is nowhere - certainly nowhere in the posted code - that reportDataSublist is being created; nowhere that reportDataList is being created; even nowhere reportData is being created. reportDataList and reportDataSublist must be created fresh every time, otherwise you are clearing out the lists already present in reportData. @Milly, you also need to refactor your code to much smaller routines - it will be easier to see and fix problems like this.
Carl Manaster
I did follow what you suggested. But as I said earlier it should not remove the key.When I debug it in Eclipse, I can see it adds a new clientCode "apple", then it adds "orange". When "orange" is added, "apple" disappears.
About the initializing of the list, even if it was cleared, it should have all the keys with the same set of list since when I clear and re-update, it updates all the list with the new values.
Yes, I agree. The initialization of the list does not affect the keys held in the map.Are you certain that there are at least two different keys?
Cambium
PROBLEM SOLVED. THANKS.