Pregunta

Estoy usando un árbol recursiva de HashMaps, específicamente mapa Hashmap donde objeto es una referencia a otra Hashmap y así sucesivamente. Esto se pasa alrededor de un algoritmo recursivo:

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());
    }
}

Yo sé a ciencia cierta Object es de tipo Hashmap<String, Object> pero estoy irritado porque tengo que suprimir la advertencia usando @SuppressWarnings("unchecked").

Voy a estar satisfecho con una solución que no sea un assert(/*entry.getValue() is of type HashMap<String, Object>*/) o una excepción cuando no lo es. Bajé la ruta Genéricos para la seguridad de tipos de compilación y si suprimir la advertencia a continuación, en contra del propósito.

Gracias por sus comentarios, ksb

¿Fue útil?

Solución

Esto es posible utilizando un método genérico con una variable de tipo recursivo. Pruebe lo siguiente:

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());
    }
}

Debería compilarse bien y sin ninguna advertencia.

Sin embargo, si usted tiene el control del mapa, y puede sustituir su propia clase, puede ser que sea más legible para hacer un nodo de clase (esto se parece a un árbol para mí), que contiene a mapa lugar. Algo así como:

public class Node {
    private Map<String, Node> children;

    ...
    // accessor methods to retrieve children ...
}

Y tienen foo tomar un Node como segundo argumento en su lugar. Sólo una sugerencia.

Otros consejos

Puede utilizar esta clase en lugar de HashMap:

public class RecursiveHashMap extends HashMap<String,RecursiveHashMap>
{
}

Su estructura de datos parece que desea representar árboles de archivos (nombres de archivo) con ella. Yo no recomiendo hacer esto con HashMap como el tipo de nodo.

Yo sugeriría utilizar el patrón de material compuesto (ver Wikipedia), el código simplificado:

abstract class Node
{
  String filename;
  Node( String filename ) { this.filename = filename; }
  abstract foo();
}

class FileNode implements Node
{
  FileNode( String filename ) { super(filename); }
  foo() { ... }
}

class DirectoryNode implements Node 
{
  Set<Node> children;
  DirectoryNode( String filename, Set<Node> children )
  {
    super(filename);
    this.children = children;
  }
  foo()
  {
    for ( Node child : children ) child.foo();
  }
}

El HashMap que estaba utilizando se reduce al conjunto que aparece en DirectoryNode.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top