0

i am working with list insertion in map and not able to understand the insertion behaviour.

public class TestList {

public static void main(String[] args) {

    String strarray[] = new String[5];

    for(int i = 0; i < 5; i++ ){

        strarray[i] = "Demo" + i;
    }

    Map<Integer, List<String>> cluesByText = new HashMap<Integer, List<String>>();
    int j = 0;
    for (String str : strarray) {

        System.out.println(str);
        List<String> s = cluesByText.get(str);
        if (s == null) {
            s = new LinkedList<String>();
            cluesByText.put(j, s);
        }

        s.add(str);
        s.add(str);
        s.add(str);
        s.remove(1);
        // why it is storing without doing cluesByText.put(j,s);
        j++;
    }

    //output is:

    System.out.println(cluesByText);

}
}

Problem is while doing insertion of list into the map and then on changing the contents of list by insert/delete operation , it is getting reflected in the list which was stored in map in previous line.

final output coming on printing map contents is.

{0=[Demo0, Demo0], 1=[Demo1, Demo1], 2=[Demo2, Demo2], 3=[Demo3, Demo3], 4=[Demo4, Demo4]}

i am not able to understand why it happening in this way as state of list is already been stored in map?

Andremoniy
  • 34,031
  • 20
  • 135
  • 241
Gaurabh
  • 21
  • 1
  • 5
  • The value of the lists you insert are still pointing to the value of the original lists. – Sam Orozco Jul 28 '16 at 19:47
  • 1
    Not related to your question, but your code doesn't make much sense. `cluesByText.get(str)` will always return null, since the keys of your Map are Integers, not Strings. – Eran Jul 28 '16 at 19:50

3 Answers3

1

This is expected behavior - you're storing a reference to the list in the map, not a copy. The same list is referred to in s, so if you add to the list through s it will indeed be seen from map - it's just two references to the same object.

Jiri Tousek
  • 12,211
  • 5
  • 29
  • 43
1

Remember that (almost) everything in Java is a REFERENCE, not a value. So, what you have is a map from a Integers to the "addresses" of lists, not the "state" of the lists.

When you go to learn the information stored in a list, the computer goes to that address to see what's there.

When assign s to be that list, it takes that address and stores it in s.

When you make changes to that list through s.add() or s.remove(), it goes to that address - the same one that's in the map - and makes the changes there.

So, when you eventually go back to that address through the map, you're looking at the same values.

The only case where that's not happening is when you assign s with the = operator: Then you're actually over-writing the address with another one, so things looking at the original address are unaffected.

Edward Peters
  • 3,623
  • 2
  • 16
  • 39
0

You have a reference to the List<String> so you can add to the list. If the map does not have an entry a new List<String> is made and the entry is added to the map. Regardless, the scope of the List<String> makes it available to work on.

Imposter
  • 253
  • 1
  • 10