0

A little confused as to why my hashmap is updating. As an example, I have the below hashmaps:

Map<String, Integer> firstMap = new HashMap<String, Integer>();

Map<Integer, Map<String, Integer>> finalMap = new HashMap<Integer, Map<String, Integer>>();

Now, when I run this:

firstMap.put("Jason", 2);
finalMap.put(1, firstMap);

firstMap.put("Jason", 15);
finalMap.put(2, firstMap);
System.out.println(finalMap);

I get this:

{1={Jason=15}, 2={Jason=15}}

Why wouldn't I get this instead? This is what I want.

{1={Jason=2}, 2={Jason=15}}

Help is greatly appreciated, thanks!

jzeta
  • 377
  • 1
  • 14
WhitneyChia
  • 746
  • 2
  • 11
  • 28

4 Answers4

2

You will need to create anotherFirstMap object (another hashmap). Not the same hashmap. samehashmap will surely update the value

firstMap.put("Jason", 2);
finalMap.put(1, firstMap);

anotherFirstMap.put("Jason", 15);
finalMap.put(2, anotherFirstMap);
System.out.println(finalMap);
Pradeep Singh
  • 1,094
  • 1
  • 9
  • 24
1

When you put something to a hashmap the hashmap just stores a reference to that object (in this case firstMap). It does not copy the object (which would lead to your expected result)!

When you do firstMap.put("Jason", 15); you change the firstMap.

When you print your finalMap all references are derefenced and printed. But both keys lead to the same object (your changed firstMap).

To illustrate that:

firstMap.put("Jason", 2);
System.out.println(firstMap); // {"Jason"=2}
finalMap.put(1, firstMap);
System.out.println(finalMap); // {1={"Jason"=15}}

firstMap.put("Jason", 15);
System.out.println(firstMap); // {"Jason"=15}
finalMap.put(2, firstMap);
System.out.println(finalMap); // {1={"Jason"=15},2={"Jason"=15}}
nCessity
  • 735
  • 7
  • 23
1

In your code when you associate "Jason" to the value 15 you are actually overwriting the value 2 because you are still using the same instance of firstMap.

In order to obtain what you are asking for your code should be instead:

Map<String, Integer> firstMap = new HashMap<String, Integer>();

Map<Integer, Map<String, Integer>> finalMap = new HashMap<Integer, Map<String, Integer>>();

firstMap.put("Jason", 2);
finalMap.put(1, firstMap);

// here we create a new instance of that HashMap
firstMap = new HashMap<String, Integer>();

firstMap.put("Jason", 15);
finalMap.put(2, firstMap);
System.out.println(finalMap);

Hope this helps.

  • Its a bad habit to reuse the same variable for a different purpose. This might hunt you down one day. – MaxZoom Jun 09 '17 at 21:02
  • 1
    While there might be cases where reusing a variable would become tricky, in this particular restricted context I've chosen to highlight the minimum modification needed to accomplish what WhitneyChia asked for. – Daniele Cremonini Jun 09 '17 at 21:47
0

Map keys are unique. When you issue a put to a Map when specifying a pre-existing key, the original value for that key will be overwritten.

From java.util.Map#put(K key, V value):

Associates the specified value with the specified key in this map (optional operation). If the map previously contained a mapping for the key, the old value is replaced by the specified value. (A map m is said to contain a mapping for a key k if and only if m.containsKey(k) would return true.)

To accomplish what you want to do, you need more than finalMap. You would need two maps: one for {Jason=2} and one for {Jason=15}.

nasukkin
  • 2,460
  • 1
  • 12
  • 19