Search code examples
javadictionaryhashmaptype-inferenceliskov-substitution-principle

How do I put to a three-dimensional, Liskov Map in Java?


I am trying to put a Map into another Map.

Map<String, ? extends Map<String, String>> test = new HashMap<String, HashMap<String, String>>();
Map<String, String> temp = new HashMap<String, String>();
test.put("foobar", temp);

But I receive this:

The method put(String, capture#1-of ? extends Map) in the type Map> is not applicable for the arguments (String, Map)

Isn't Map<String,String> the same as ? extends Map<String,String>?


Solution

  • The outer Map test uses an upper wildcard value which prevents values being added whereas the Map temp does not.

    You could use

    Map<String, Map<String, String>> test = new HashMap<String, Map<String, String>>();
                ^                                               ^
                |-----changed LHS type--- must be matched with -|                                               
    

    The bounded wildcard syntax Map<String, ? extends Map<String, String>> means the Map uses a value of some unknown type that extends Map. The compiler prevents all values except null being added.

    Notice also the right hand side value has a Map type rather than a HashMap as generics are not covariant which means generic types on the right hand side assigned values must match exactly with those from the left hand side declaration.