递归 Hashmap 的 Java 泛型类型安全警告

发布于 2024-08-25 06:43:03 字数 709 浏览 6 评论 0原文

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

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 但我很恼火,因为我必须使用 抑制警告>@SuppressWarnings(“未选中”)

我会对一个解决方案感到满意,该解决方案要么执行 assert(/*entry.getValue() is of type HashMap*/) ,要么在不是类型时抛出异常。为了编译类型安全,我采用了泛型路线,如果我抑制警告,那么它就达不到目的了。

谢谢您的评论, KSB

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

冬天的雪花 2024-09-01 06:43:03

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

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 类(对我来说这看起来像一棵树)可能更具可读性,它包含一个 Map。类似于:

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

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

并让 fooNode 作为其第二个参数。只是一个建议。

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.

醉生梦死 2024-09-01 06:43:03

您可以使用此类代替 HashMap:

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

You can use this class instead of HashMap:

public class RecursiveHashMap extends HashMap<String,RecursiveHashMap>
{
}
云醉月微眠 2024-09-01 06:43:03

您的数据结构看起来像是您想用它来表示文件树(文件名)。我不建议使用 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。

Your data structure looks like you want to represent trees of files (filenames) with it. I'd not recommend to do this with HashMap as the node type.

I'd suggest to use the composite pattern (see wikipedia), simplified code:

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

The HashMap you were using boils down to the Set appearing in DirectoryNode.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文