I try to refresh my Java skills. But now I stuck at a hashmap. I don't get the right object back. Here is my example code:
public class Sample {
 private static Map<String, Map<String, String>> peaks = new HashMap<String, Map<String, String>>();
 private final String name;
 public Sample(String name) {
 this.name = name;
 this.peaks = new HashMap<String, Map<String, String>>();
 }
 public static Map<String, Map<String, String>> getPeaks() {
 return peaks;}
 public static void addPeak(String peakName, String value) {
 Map<String, String> peak = new HashMap<String, String>();
 peak.put("value", value);
 peaks.put(peakName, peak);
 }
}
public class Main {
 static Map<Integer, Sample> sample = new HashMap<Integer, Sample>();
 public static void main(String[] args) {
 Sample sam = new Sample("Test1");
 sample.put(1, sam);
 sample.get(1).addPeak("A", "1");
 sam = new Sample("Test2");
 sample.put(2, sam);
 sample.get(2).addPeak("B", "123");
 System.out.println(sample.get(1).getPeaks().toString()); 
 System.out.println(sample.get(2).getPeaks().toString()); 
 System.out.println(sample.get(4).getPeaks().toString()); 
 }
}
EVERYTIME THE OUTPUT IS: {B={value=123}}
I don't know which part is wrong. Did I miss something?
- 
 what are you getting? please paste your output.Freak– Freak2013年09月25日 12:14:13 +00:00Commented Sep 25, 2013 at 12:14
- 
 @freak It's there, buried. Joko, please post the output as a separate block instead of hiding it inside a comment.chrylis -cautiouslyoptimistic-– chrylis -cautiouslyoptimistic-2013年09月25日 12:14:52 +00:00Commented Sep 25, 2013 at 12:14
- 
 o just see :D @chrylisFreak– Freak2013年09月25日 12:18:26 +00:00Commented Sep 25, 2013 at 12:18
- 
 If I only remove static I get much more errors (but this is another topic then). I will read about static...Joko– Joko2013年09月25日 12:20:05 +00:00Commented Sep 25, 2013 at 12:20
- 
 "sample.get(4).getPeaks()" would throw an NPEbobah– bobah2013年09月25日 12:21:10 +00:00Commented Sep 25, 2013 at 12:21
3 Answers 3
This map is static :
private static Map<String, Map<String, String>> peaks = new HashMap<String, Map<String, String>>();
Hence, every call to Sample.getPeaks() points to the same Map.
//getPeaks() returns the same map in both cases.
// In other words : sample.get(1).getPeaks() == sample.get(2).getPeaks()
System.out.println(sample.get(1).getPeaks().toString()); 
System.out.println(sample.get(2).getPeaks().toString());
// This is equivalent to
Map<String, Map<String, String>> myStaticMap = Sample.getPeaks();
System.out.println(myStaticMap.toString()); 
System.out.println(myStaticMap.toString()); 
Comments
The methods getPeaks and addPeaks as well as the map peaks are static! That means they only exist once (per class), not once per instance of Sample.
So everytime you create a new Sample instance, you're overwriting the static field peaks in the constructor! Remove the static keyword!
Comments
Perhaps you were trying to learn how to use nested Maps, but for this implementation, couldn't you simply create a Map<String, String>? The reason I'm asking is because in addPeak you've made a call to peak.put("value", value), with the hardcoded string "value", which may be unnecessary. Here's some code which may satisfy what you're interested in:
public class WhyMapOfMap {
 // Simpler map
 private Map<String, String> peaks;
 private String name;
 public WhyMapOfMap(String name) {
 this.name = name;
 peaks = new HashMap<>();
 }
 public Map<String, String> getPeaks() {
 return peaks;
 }
 public void addPeak(String peakName, String value) {
 peaks.put(peakName, value);
 }
}
Then you may access the map normally sample.get(key).getPeaks().