0

I'm totally at loss. Here is my code

HashMap>> themap = new HashMap>>(); HashMap> outerMap = new HashMap>();

...
//themap is populated through OnCreate(), and works fine.

    @SuppressWarnings("StatementWithEmptyBody")
        @Override
        public boolean onNavigationItemSelected(MenuItem item) {
                String currentfragment = "my_string"
                ...
                HashMap<String, HashMap<String, HashMap<String, Integer>>> copymap = copy(themap);
                System.out.println("1" + themap);
                outerMap.putAll(copymap.get(currentfragment));
                System.out.println("2" + themap);
                ...
        }

In another method, some values of themap are changed. The problem is that when onNavigationItemSelected is called, the first .println() prints the right map, with the values changed, and the second .println() prints themap with its starting values, before they were changed. What did I do wrong?

EDIT: I've followed the instructions of How to copy HashMap (not shallow copy) in Java , but it still doesn't work. I've updated my previous code, and here is my copy method:

public static HashMap<String, HashMap<String, HashMap<String, Integer>>> copy(HashMap<String, HashMap<String, HashMap<String, Integer>>> original) {
    HashMap<String, HashMap<String, HashMap<String, Integer>>> copy = new HashMap<>();
    for (Map.Entry<String, HashMap<String, HashMap<String, Integer>>> entry : original.entrySet()) {
        HashMap<String, HashMap<String, Integer>> copyInnerMap = new HashMap<>();
        for (Map.Entry<String, HashMap<String, Integer>> innerEntry : entry.getValue().entrySet()) {
            HashMap<String, Integer> innerInnerMap = innerEntry.getValue();
            HashMap<String, Integer> copiedInnerInnerMap = new HashMap<>();
            for (Map.Entry<String, Integer> innerInnerMapEntry : innerInnerMap.entrySet()) {
                copiedInnerInnerMap.put(innerInnerMapEntry.getKey(), innerInnerMapEntry.getValue());
            }
            copyInnerMap.put(innerEntry.getKey(), copiedInnerInnerMap);
        }
        copy.put(entry.getKey(), copyInnerMap);
    }
    return copy;
}

EDIT2: I've updated my copy method so that it's deep enough.
Here is the first output:
1{compu={Day1={Work hours=0, Study hours=0, Day grades=-1, Sheets filled=0, Fun=0}, Day2={Work hours=0, Study hours=0, Day grades=-1, Sheets filled=0, Fun=0}, Day3={Work hours=0, Study hours=0, Day grades=-1, Sheets filled=0, Fun=0}}, chem={Day1={Work hours=0, Study hours=0, Day grades=-1, Sheets filled=0, Fun=0}, Day2={Work hours=0, Study hours=0, Day grades=-1, Sheets filled=0, Fun=0}, Day3={Work hours=0, Study hours=0, Day grades=-1, Sheets filled=0, Fun=0}}, math={Day1={Work hours=0, Study hours=0, Day grades=-1, Sheets filled=0, Fun=0}, Day2={Work hours=0, Study hours=0, Day grades=-1, Sheets filled=0, Fun=2}, Day3={Work hours=0, Study hours=0, Day grades=-1, Sheets filled=0, Fun=0}}, physic={Day1={Work hours=0, Study hours=0, Day grades=-1, Sheets filled=0, Fun=0}, Day2={Work hours=0, Study hours=0, Day grades=-1, Sheets filled=0, Fun=0}, Day3={Work hours=0, Study hours=0, Day grades=-1, Sheets filled=0, Fun=0}}, None={Day1={Work hours=0, Study hours=0, Day grades=-1, Sheets filled=0, Fun=0}, Day2={Work hours=0, Study hours=0, Day grades=-1, Sheets filled=0, Fun=2}, Day3={Work hours=0, Study hours=0, Day grades=-1, Sheets filled=0, Fun=0}}}

And the second:
2{compu={Day1={Work hours=0, Study hours=0, Day grades=-1, Sheets filled=0, Fun=0}, Day2={Work hours=0, Study hours=0, Day grades=-1, Sheets filled=0, Fun=0}, Day3={Work hours=0, Study hours=0, Day grades=-1, Sheets filled=0, Fun=0}}, chem={Day1={Work hours=0, Study hours=0, Day grades=-1, Sheets filled=0, Fun=0}, Day2={Work hours=0, Study hours=0, Day grades=-1, Sheets filled=0, Fun=0}, Day3={Work hours=0, Study hours=0, Day grades=-1, Sheets filled=0, Fun=0}}, math={Day1={Work hours=0, Study hours=0, Day grades=-1, Sheets filled=0, Fun=0}, Day2={Work hours=0, Study hours=0, Day grades=-1, Sheets filled=0, Fun=0}, Day3={Work hours=0, Study hours=0, Day grades=-1, Sheets filled=0, Fun=0}}, physic={Day1={Work hours=0, Study hours=0, Day grades=-1, Sheets filled=0, Fun=0}, Day2={Work hours=0, Study hours=0, Day grades=-1, Sheets filled=0, Fun=0}, Day3={Work hours=0, Study hours=0, Day grades=-1, Sheets filled=0, Fun=0}}, None={Day1={Work hours=0, Study hours=0, Day grades=-1, Sheets filled=0, Fun=0}, Day2={Work hours=0, Study hours=0, Day grades=-1, Sheets filled=0, Fun=0}, Day3={Work hours=0, Study hours=0, Day grades=-1, Sheets filled=0, Fun=0}}}

SemAntys
  • 316
  • 2
  • 15
  • `putAll` & `put` does not deep copy the object to the new `outerMap`, it just store the reference in the `Map`. – xingbin Aug 31 '18 at 17:11
  • But why has `themap` changed after the line where I copy its content? What should I do to copy its content without modifying it? – SemAntys Aug 31 '18 at 17:14
  • maybe outer method changed the value via `outerMap` – xingbin Aug 31 '18 at 17:17
  • Could you look at my edit, please? – SemAntys Aug 31 '18 at 17:38
  • You should not edit your question to put in the answer. Answers are separate from questions. – Patrick Parker Aug 31 '18 at 20:19
  • @PatrickParker Sorry, should I re-edit it to put my previous copy method? By the way, I followed your instructions about the way to create deep clones of hashmap using serialization, and I think my problem is about my construction of `themap`. I'm working on it, I will update the thing when I find an answer. Thanks for your help anyways! – SemAntys Aug 31 '18 at 20:25
  • Look, the problem is that you are printing `themap` instead of `copymap` – Patrick Parker Sep 01 '18 at 05:43

1 Answers1

0

Since you have 2 level of hashmaps, you are not copying them deep enough. Try replacing your outerMap.putAll(copymap.get(currentfragment)); with the following code

HashMap<String, HashMap<String, Integer>> sample = themap.get(currentfragment);
for (String s : sample.keySet()) {
    outerMap.put(s, new HashMap<>(sample.get(s)));
}
Magdrop
  • 568
  • 3
  • 13