5

我正在使用哈希映射的递归树,特别是哈希映射映射,其中 Object 是对另一个哈希映射的引用,依此类推。这将通过递归算法传递:

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

我肯定知道Object是类型Hashmap<String, Object>,但很恼火我必须使用@SuppressWarnings("unchecked").

assert(/*entry.getValue() is of type HashMap<String, Object>*/)我会对执行 a或在未执行时抛出异常的解决方案感到满意。为了编译类型安全,我沿着泛型路线走下去,如果我抑制警告,那么它就达不到目的。

谢谢你的评论,ksb

4

3 回答 3

5

您可以使用此类代替 HashMap:

public class RecursiveHashMap extends HashMap<String,RecursiveHashMap>
{
}
于 2010-03-14T21:35:05.863 回答
5

这可以使用带有递归类型变量的泛型方法。尝试以下操作:

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

应该可以正常编译而没有任何警告。

但是,如果您可以控制地图,并且可以替换您自己的类,则创建一个包含地图的类 Node(这对我来说就像一棵树)可能更具可读性。就像是:

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

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

并将fooaNode作为其第二个参数。只是一个建议。

于 2010-03-14T21:45:24.767 回答
1

您的数据结构看起来像您想用它来表示文件树(文件名)。我不建议使用 HashMap 作为节点类型来执行此操作。

我建议使用复合模式(参见维基百科),简化代码:

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

您使用的 HashMap 归结为出现在 DirectoryNode 中的 Set。

于 2010-03-14T22:04:09.427 回答