1

I am having trouble with implementing HashMaps with ArrayListsin my java class. The thing is it keeps adding objects to the ArrayList is the HashMap even though I am not updating my HashMap.

This is the code that I can not understand how works:

HashMap<String, ArrayList<String>> map = new HashMap<>();

ArrayList<String> array = new ArrayList<String>();
array.add("One");
array.add("Two");

map.put("Key", array);

array.add("Three"); //2. Why does this get added to the HashMap?

System.out.println(map1.get("Key"));
//1. This print out [One, Two, Three].. When it should be [One, Two]!
Peter
  • 1,848
  • 4
  • 26
  • 44
  • 4
    That's how references work in java. What you have put in the map is a reference to the list, so any changes in the list will show up when you print the map. – Paul Boddington Oct 28 '15 at 14:02
  • `add()` does not copy the list, it just inserts a reference. – Andreas Oct 28 '15 at 14:03
  • This is how Java works. map.getKey("Key") and your array variable are referencing the same location in memory eseentially. Whether you add an element via the "array" reference or via the reference returned by map.getKey("key), you're adding elements to the same place in memory. – bdkosher Oct 28 '15 at 14:04

5 Answers5

3

The ArrayList is passed by reference to the map.put() call. It means no copying, after the call your array variable refers to the same object. If you copy when adding the entry then it will work: map.put("Key", new ArrayList<String>(array));

erosb
  • 2,943
  • 15
  • 22
1
map.put("Key", array);

That means you are adding a reference of list to the map. Hence the changes to that reference can be seen everywhere.

If you don't want to do that, create a new list and add to it.

Suresh Atta
  • 120,458
  • 37
  • 198
  • 307
1

This is the expected behaviour. You put the list into the map, not a copy, the list itself. So if you later modify the list, the list inside the map (which is the actual list) will also be modified.

Paco Abato
  • 3,920
  • 4
  • 31
  • 54
1

Because you add a reference to a list into your map, and you still hold the original reference, when you amend that list, you're amending the list referenced within the map.

Remember that Java passes references to objects around (not copies), and if you have a mutable object referenced within a container, that object can still be changed.

If you want to avoid this behaviour, you need to make a defensive copy. Note that this applies to mutable objects generally (not just collections) and you need to be clear when you pass references around and hold them, that anyone else holding that reference can change/mutate your object without your control. It's often preferable to create and pass around immutable objects instead

Brian Agnew
  • 268,207
  • 37
  • 334
  • 440
0

you are adding a reference of your ArrayList as the value to your map.

so if you want only the first two value, you can simply point your ArrayList to null to ensure you don't add stuff to it then re-initiate it

HashMap<String, ArrayList<String>> map = new HashMap<>();

ArrayList<String> array = new ArrayList<String>();
array.add("One");
array.add("Two");

map.put("Key", array);

array=null; //note this isn't really necessary, just a precaution that you won't change the value of arraylist inside the map using this refrence
array=new ArrayList<String>(map.get("key"));
array.add("Three"); 

System.out.println(map1.get("Key"));

output:

[one, two]

nafas
  • 5,283
  • 3
  • 29
  • 57