【问题标题】:Tree data structure (Generics)树数据结构(泛型)
【发布时间】:2015-12-07 15:11:21
【问题描述】:

我正在实现一个简单的 Tree 数据结构。 我的目标是在 Tree 类中创建一个 Node 类型的对象。 在这种情况下,我不明白如何管理泛型。

这是我的细树结构:

public class RBT<K extends Comparable<K>, V> {

    Node<K,V> a = null;
    Node<Integer,String> b = null;

    public RBT() {
        this.a = new Node<K,V>(new Integer(1), new String("node1")); // ERROR
        this.b = new Node<Integer, String>(new Integer(1), new String("node1"));

        this.a = this.b; // ERROR!
    }

    public void newNode(K key, K value) {
        Node<K,V> test = new Node<K,V>(key, value); // ERROR
    }

    public static void main(String[] args) {
        RBT<Integer,String> rbt = new RBT<Integer,String>();
        rbt.newNode(new Integer(2), new String("node2")); // ERROR!
    }
}

这是我的节点表示:

public class Node<K,V> {
    private Node<K,V> father;
    private Node<K,V> left;
    private Node<K,V> right;

    private K key;
    private V value;

    Node(K key, V value) {
        this.father = this.left = this.right = null;

        this.key = key;
        this.value = value;
    }
}

提前感谢您的帮助。

【问题讨论】:

  • 最后我找到了另一个有趣的解决方案。我已经在 RBT 类 private class Node { } 中将 Node 类声明为私有(注意我省略了 )。这样可以更轻松地管理泛型。

标签: java generics tree


【解决方案1】:

首先,

this.a = new Node<K,V>(new Integer(1), new String("node1")); // ERROR

当你给它确切的类型时,你不能将 K,V 添加为泛型。 所以删除它

 this.a = new Node(new Integer(1), new String("node1"));

其次,

this.a = this.b; // ERROR!

this.a 具有泛型&lt;K,V&gt;,而this.b 具有&lt;Integer,String&gt;。因此,您可以通过强制转换来解决不匹配问题,因为您确切地知道 K,V 将是 Integer,String

this.a = (Node<K, V>) this.b;

你的方法签名也是错误的

public void newNode(K key, K value) {
                           ^ should be V
        Node<K,V> test = new Node(key, value); // ERROR
    }

【讨论】:

  • 感谢@Murat,我用您的建议替换了代码,但this.a = (RBT&lt;K, V&gt;.Node&lt;K, V&gt;) this.b; 抛出了以下错误错误:cannot find symbol: this.a = (RBT&lt;K, V&gt;.Node&lt;K, V&gt;) this.b; symbol: class Node, location: class RBT&lt;K,V&gt;
  • 最后你的解决方案类似于@Yi Zhang的代码。在构造函数签名前加@SuppressWarnings("unchecked"),绕过问题,非常感谢。但我仍然不相信。
  • @JohnMòf 这不是编译器的问题。编译器告诉您您正在执行未经检查的强制转换,因为您知道 K,V 将是 String, Integer,但编译器不会。
【解决方案2】:

我是 Java 泛型的菜鸟。你可以这样做。

public class RBT<K extends Comparable<K>, V> {

    Node<K,V> a = null;
    Node<Integer,String> b = null;

    public RBT() {
        this.a = new Node(new Integer(1), new String("node1")); // ERROR
        this.b = new Node<Integer, String>(new Integer(1), new String("node1"));

        this.a = (Node<K, V>) this.b; // ERROR!
    }

    public void newNode(K key, V value) {
        Node<K,V> test = new Node(key, value); // ERROR
    }

    public static void main(String[] args) {
        RBT<Integer,String> rbt = new RBT<Integer,String>();
        rbt.newNode(new Integer(2), new String("node2")); // ERROR!
    }
}

请原谅我糟糕的英语。我不是母语人士。

【讨论】:

  • 这可以生成一个warning: [unchecked] unchecked cast
  • @JohnMòf 是的,编译器会生成警告,但不影响结果。我不知道如何修复警告,除了在上面添加 SuppressWarning它。对不起。
  • 我调查了更多,你是对的。感谢您的帮助。
【解决方案3】:

正如你已经发现的那样,你不能写

new Node<K, V>

你必须指定类型。

Node<Integer, String> node = new Node<Integer, String>(new Integer(1), new String("anything"))

【讨论】:

  • KV 在他使用它们的地方实际上是“类型”......问题是他没有将这些类型的对象作为参数传递......
猜你喜欢
  • 2014-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-30
  • 2010-12-14
  • 2010-10-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多