Search code examples
javagenericshashmaptype-safetyrecursive-datastructures

Java Generics Type Safety warning with recursive Hashmap


I'm using a recursive tree of hashmaps, specifically Hashmap map where Object is a reference to another Hashmap and so on. This will be passed around a recursive algorithm:

foo(String filename, Hashmap<String, Object> map)
{
    //some stuff here
    for (Entry<String, Object> entry : map.entrySet()) 
    {
       //type warning that must be suppressed
       foo(entry.getKey(), (HashMap<String, Object>)entry.getValue());
    }
}

I know for sure Object is of type Hashmap<String, Object> but am irritated that I have to suppress the warning using @SuppressWarnings("unchecked").

I'll be satisfied with a solution that does either a assert(/*entry.getValue() is of type HashMap<String, Object>*/) or throws an exception when it isn't. I went down the Generics route for compile type safety and if I suppress the warning then it defeats the purpose.

Thank you for your comments, ksb


Solution

  • This is possible using a generic method with a recursive type variable. Try the following:

    public <T extends Map<String, T>> void foo(String filename, T map) {
        //some stuff here
        for (Map.Entry<String, T> entry : map.entrySet())  {
            foo(entry.getKey(), entry.getValue());
        }
    }
    

    Should compile fine without any warnings.

    However, if you have control of the map, and can substitute your own class, it might be more readable to make a class Node (this looks like a tree to me), that contains a Map instead. Something like:

    public class Node {
        private Map<String, Node> children;
    
        ...
        // accessor methods to retrieve children ...
    }
    

    And have foo take a Node as its second argument instead. Just a suggestion.