我正在使用一个递归的hashmaps树,特别是Hashmap map,其中Object是对另一个Hashmap的引用,依此类推。这将通过递归算法传递:
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>*/)
,也可以在异常时抛出异常。我沿着Generics路线走了编译类型安全,如果我压制警告那么它就会失败。
感谢您的评论, KSB
答案 0 :(得分:5)
您可以使用此类而不是HashMap:
public class RecursiveHashMap extends HashMap<String,RecursiveHashMap>
{
}
答案 1 :(得分: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(这对我来说就像一棵树)可能更具可读性,包含 a改为映射。类似的东西:
public class Node {
private Map<String, Node> children;
...
// accessor methods to retrieve children ...
}
让foo
取代Node
作为第二个参数。只是一个建议。
答案 2 :(得分: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。