1

look at this small example

import java.util.ArrayList;
import java.util.HashMap;

public class Foo {
public static void main(String[] args) {

    ArrayList<Integer> array = new ArrayList<Integer>();
    HashMap<String, ArrayList<Integer>> foo = new HashMap<String,ArrayList<Integer>>();

    for (int i = 0; i < 20; i++)
        array.add(i);

    foo.put("1", array);
    // array.clear();

    System.out.println(foo.get("1").size());
 }
}

Now, if use array.clear() it automatically delete all values of the arrayList associated with the specified key inside the hashmap

how can I prevent this?

in such a way that:

  • I can perform array.clear(); (after entering values ​​in hashmap) and only delete the values of ArrayList<Integer> array

  • The values ,​​of the array associated with that key, won't deleted inside the hashmap

if you launch this program,it will print 20 without using array.clear();, 0 instead

OiRc
  • 1,602
  • 4
  • 21
  • 60
  • Are you sure you understand that java uses references to objects everywhere? If you store reference to array in HashMap then it is the same object as the one your local variable refers to. – Andrey May 05 '14 at 13:23
  • in your hashmap declaration you are giving the reference to the same object so it is obvious that it will get deleted from both places(well clearly it does not exist at two places only one array exists), you use ONE array in TWO places.as @Andrey said please go through how java uses references to objects to understand it better. – madteapot May 05 '14 at 13:27
  • CiMat, see my answer.. – niiraj874u May 05 '14 at 13:28

4 Answers4

2

It is deleting the maps keys elements because both are same objects. You have to make a shallow copy to make both lists separate

Creating a shallow copy is pretty easy though:

List<Integer> newList = new ArrayList<Integer>(oldList);

Here is the code:

public class Foo {
    public static void main(String[] args) {

        ArrayList<Integer> array = new ArrayList<Integer>();
        HashMap<String, ArrayList<Integer>> foo = new HashMap<String, ArrayList<Integer>>();

        for (int i = 0; i < 20; i++)
            array.add(i);

        ArrayList<Integer> newList = new ArrayList<Integer>(array);

        foo.put("1", newList);
        array.clear();

        System.out.println(foo.get("1").size());
    }

}
OldMcDonald
  • 594
  • 13
  • 36
niiraj874u
  • 2,180
  • 1
  • 12
  • 19
2

foo.get("1") and array refer to the same object. You need foo.put("1", new ArrayList<Integer>(array));.

sp00m
  • 47,968
  • 31
  • 142
  • 252
1

Just put not the ArrayList itself, but it's copy:

foo.put("1", new ArrayList<Integer>(array));

If you want to put the array itself, you must have it unmodifiable:

Map<String, List<Integer>> foo = ...;
...
List<Integer> unmodifiableArray = Collections.unmodifiableList(array);
foo.put(unmodifiableArray);
Dmitry Ginzburg
  • 7,391
  • 2
  • 37
  • 48
1

The problem is that you do not write "new" objects into that map. In other words your list named "array", it's exactly the same memory address as that list in a map, so... if you change 1, changes appear in both places.

demongolem
  • 9,474
  • 36
  • 90
  • 105