2

I have this problem where I tried to create a 2D HashMap by nesting one of them inside another but I have this weird issue where some of the data gets overridden by more data and I’m not really sure how to fix it. Many thanks for all your time and effort in advance.

import java.util.HashMap;


public static void main(String args[]) {

    HashMap<Integer, HashMap<Integer, Integer>> outerMap = new HashMap<Integer, HashMap<Integer, Integer>>();
    HashMap<Integer, Integer> innnerMap = new HashMap<Integer, Integer>();
    int number;

    innnerMap.put(5, 100);
    outerMap.put(6, innnerMap);

    innnerMap.put(5, 77);
    outerMap.put(10, innnerMap);

    innnerMap.put(33, 88);
    outerMap.put(6, innnerMap);

    System.out.println(outerMap.get(6).get(5));

}

}

The output this code gives is 77 even though it’s clear that 100 is the intended output. I still say dark magic is to blame here :/

EDIT: My post is completely different to the one I’m marked as a duplicate to, my post is about nested HashMaps and there’s is about list and static fields.

This post has been answered but it’s not a duplicate!

sam
  • 69
  • 6

4 Answers4

4

If you add the same inner HashMap multiple times to the outer HashMap, you will see that "data gets overridden by more data".

You have to create a new inner HashMap before adding it to the outer HashMap :

When you want to add data to the inner map you have to check if you didn't already add it to the outer map, and if you did you have to use the existing inner map.

Java 8 has a short and nice way of implementing what you need :

HashMap<Integer, HashMap<Integer, Integer>> outerMap = new HashMap<>();
HashMap<Integer, Integer> innerMap = null;

innerMap = outerMap.computeIfAbsent(6, HashMap::new); // this will put a new inner HashMap 
                                                      // in the outer HashMap if it
                                                      // doesn't contain a value for the
                                                      // given key 6, or return the
                                                      // existing inner map otherwise
innerMap.put(5, 100);

innerMap = outerMap.computeIfAbsent(10, HashMap::new);
innerMap.put(5, 77);

innerMap = outerMap.computeIfAbsent(6, HashMap::new);
innerMap.put(33, 88);

System.out.println(outerMap.get(6).get(5));

This code was added by user1121883. You can use it if you can't use Java 8 :

public static HashMap<Integer,Integer> get(Integer key, HashMap<Integer, HashMap<Integer, Integer>> map){
    HashMap<Integer,Integer> innerMap = map.get(key);
    if(innerMap == null){
        innerMap = new HashMap<>();
        map.put(key, innerMap);
    }
    return innerMap;
}

    HashMap<Integer, HashMap<Integer, Integer>> outerMap = new HashMap<Integer, HashMap<Integer, Integer>>();

    HashMap<Integer, Integer> innnerMap = get(6, outerMap);
    innnerMap.put(5, 100);

    innnerMap = get(10, outerMap);
    innnerMap.put(5, 77);

    innnerMap = get(6, outerMap);
    innnerMap.put(33, 88);

    System.out.println(outerMap.get(6).get(5));
Eran
  • 387,369
  • 54
  • 702
  • 768
  • True but that will give null as an output, is this because the new innermap will destroy the old one? and how would I prevent this? – sam Sep 01 '16 at 11:44
  • @sam I was in the process of editing my answer when some other person edited my answer which made my changes disappear. This is annoying. – Eran Sep 01 '16 at 11:51
  • thanks for putting your awenser up and keeping user1121883's awenser there – sam Sep 01 '16 at 12:05
  • Just a warning for those that stuble over this question and like the concise `computeIfAbsent(6, HashMap::new);` style: this does not quite do what one might expect - it works, but only because `HashMap` has a constructor accepting an `int`, and this one is invoked: [`public HashMap​(int initialCapacity)`](https://docs.oracle.com/en/java/javase/15/docs/api/java.base/java/util/HashMap.html#%3Cinit%3E(int)). It does not work for other types of keys. Therefore, it is more correct to use `k -> new HashMap<>()` as the mapping function. – Hulk Dec 23 '20 at 09:16
2

You put two values with the same key

innnerMap.put(5, 100);
innnerMap.put(5, 77);

That's why it override the value. If you create new instance of innnerMap each time the problem will be solved

innnerMap = new HashMap<Integer, Integer>();
innnerMap.put(5, 100);
Guy
  • 46,488
  • 10
  • 44
  • 88
1

You assign the same keys to outer map and inner map, the values were rewritten. If the key exists it checks the hash code if the hash code equals, hash map perform equals between the keys. If they are equals the key will be rewritten with the new key value pair

Vitalii Kravchenko
  • 395
  • 1
  • 2
  • 9
0

Usually this will happen when you declare your innermap out of while loop. Make sure you create new instance for innermap everytime.