Question

I have a HashSet which is inside a HashMap which in turn is inside another HashMap. When I try to add elements to this HashSet under one key, the elements are added to all other keys of the outer HashMap. Here is my code:

import java.util.HashSet;
import java.util.HashMap;
import java.util.Map;

public class Student {
    public static void main(String args[]) {
        Map<String, HashMap<Integer,HashSet<Integer>>> sections
            = new HashMap<String, HashMap<Integer,HashSet<Integer>>>();

        HashMap<Integer, HashSet<Integer>> empty_map = new HashMap<Integer, HashSet<Integer>>();
        sections.put("A", empty_map);
        sections.put("B", empty_map);
        int strength = 0;
        int init = 1;
        int id1 = 1,id2 = 5;
        while (strength < 3) {

            // Add elements only to the HashSet under the HashMap of key "A"

            if (! sections.get("A").containsKey(init))
                sections.get("A").put(init, new HashSet<Integer>());

            // If the key init is already present then simply add values to it.
            sections.get("A").get(init).add(id1);
            sections.get("A").get(init).add(id2);

            System.out.println(sections);

        strength++;
        init++;
        }
    }

}

The output of this code is:

{A={1=[1, 5]}, B={1=[1, 5]}}
{A={1=[1, 5], 2=[1, 5]}, B={1=[1, 5], 2=[1, 5]}}
{A={1=[1, 5], 2=[1, 5], 3=[1, 5]}, B={1=[1, 5], 2=[1, 5], 3=[1, 5]}}

Why are the elements getting added to the HashMap under "B" key?

Was it helpful?

Solution

The problem is here:

HashMap<Integer, HashSet<Integer>> empty_map = new HashMap<Integer, HashSet<Integer>>();
sections.put("A", empty_map);
sections.put("B", empty_map);

You're adding the same object for both A and B keys. So any changes that modify the map associated with A also modify the one associated with B and vice versa.

Think of a situation like this:

enter image description here

You have to create a new object for each key.

sections.put("A", new HashMap<Integer, HashSet<Integer>>());
sections.put("B", new HashMap<Integer, HashSet<Integer>>());

And it outputs:

{A={1=[1, 5]}, B={}}
{A={1=[1, 5], 2=[1, 5]}, B={}}
{A={1=[1, 5], 2=[1, 5], 3=[1, 5]}, B={}}

OTHER TIPS

The keys "A" and "B" both "point to" the same HashMap. (Objects are passed by reference.) Try writing instead:

sections.put("A", new HashMap<Integer, HashSet<Integer>>());
sections.put("B", new HashMap<Integer, HashSet<Integer>>());
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top