0

I have a hashmap which has a hashset of strings as values. I worked out a test code - shown below :

 public static void main(String args[]) {

    HashMap<String, HashSet<String>> hmap = new HashMap<String, HashSet<String>>();

    HashSet<String> set = new HashSet<String>();
    set.add("a");
    set.add("b");
    set.add("c");
    set.add("d");

    hmap.put("a", set);

    set.clear();// = new HashSet<String>();
    set.add("a");
    set.add("b");

    hmap.put("c", set);

    set.clear();// = new HashSet<String>();
    set.add("a");
    set.add("b");
    set.add("c");

    hmap.put("b", set);

    for (Entry<String, HashSet<String>> entry : hmap.entrySet())
    {
        System.out.println(entry.getKey() + " - " + entry.getValue());
    }
  }

I am reusing the same hashset to populate the values in the hashmap. But I see that hashset.clear() is not clearing the values as expected.

The code I get for the above code is -

b - [b, c, a]
c - [b, c, a]
a - [b, c, a]

So, the all the values are overwritten by the last HashSet. I read javadoc for clear() and the expected behavior is that the elements of the hashset are removed on calling clear.

Output when I use new HashSet instead of hashset.clear()

b - [b, c, a]
c - [b, a]
a - [d, b, c, a]

This is the output I am expecting.

The reason I do not want to use set = new HashSet<String> each time is because I do not want create too many hashsets ( the size of hashmap is expected to be large). Am I missing something?

Thanks for your help.

maddie
  • 629
  • 10
  • 29
  • 1
    you're using the **same** set so what you'll get is only the most recent values after the last "clear" – Nir Alfasi Apr 13 '17 at 23:47
  • 3
    Every value of your map is the *same set object*. – user2357112 Apr 13 '17 at 23:47
  • 8
    "The reason I do not want to use set = new HashSet each time is because I do not want create too many hashsets" - but you *need* multiple hashsets. One isn't enough! – user2357112 Apr 13 '17 at 23:47
  • The three elements in map are referencing the same instance of set. When you print them, they read its last status (the content for b). All the things you do before are of no use. – Alfabravo Apr 13 '17 at 23:49
  • 1
    Well-written questions are often a rarity nowadays :) Yours has a test-case, what you got, and what you expected, so can't ask for much more! – Oliver Charlesworth Apr 13 '17 at 23:50
  • @Oliver If only it were a Junit test ;) – OneCricketeer Apr 13 '17 at 23:53
  • Thank you for the quick responses. So , is there anyway apart from creating a new hashset every time? I guess, not? – maddie Apr 13 '17 at 23:55
  • If you move the `hmap.put` line *above* the corresponding `set.add` lines, you'll see the map will still show the set containing the elements that were added afterwards. That should help to demonstrate what is happening. If you only call `new HashSet` once, there is only one `HashSet` object in memory. – Boann Apr 14 '17 at 00:04
  • 1
    @maddie : 2 tips for the future — 1) Use the [Java diamond operator](https://www.google.com/search?q=java+diamond+operator) to simplify generics... this `HashMap> hmap = new HashMap>();` becomes this `HashMap> hmap = new HashMap<>();` the compiler can figure out the types needed on the right-hand side. 2) Use _interfaces_ in declarations, classes when creating instances: `Map> hmap = new HashMap<>();` / `Set set = new HashSet<>();` – Stephen P Apr 14 '17 at 00:51
  • @Stephen P Thanks for the suggestions, I will keep those in mind while coding. – maddie Apr 14 '17 at 23:07

2 Answers2

1

In fact, you are modifying the same set object i.e., all of your 3 keys (inside the Map) hold the reference to the same set object.

So, if you want to clear and work on the each set independently, just use the new set object for each key inside the Map:

set = new HashSet<String>();
Vasu
  • 21,832
  • 11
  • 51
  • 67
1

If you print the address of the HashMap or Debuging it, you can see that all Objects are refering the same address.

If you are using the eclipse or netbeans, you can make a breakpoint and see the address and status of each step.

Good Luck

Kwang-Chun Kang
  • 351
  • 3
  • 12