【问题标题】:Java Generics Comparable | implement compareToJava 泛型可比 |实现 compareTo
【发布时间】:2013-12-04 10:34:56
【问题描述】:

我遇到了 java 泛型的问题。我的计划是使用具有总排序的泛型实现二叉搜索树(键和值)。我首先创建了这个KeyValPair,然后遇到了获取正确 compareTo 方法的问题。

public class KeyValPair <V extends Comparable<V>>
        implements Comparable<KeyValPair<V>>{

    private int key;
    private V value;
    private KeyValPair<V> leftchild;
    private KeyValPair<V> rightchild;

    public KeyValPair(int k,V v){
        key=k;
        value=v;
    }

    public Comparable<?> getKey(){
        return key;
    }

    public Comparable<?> getValue(){
        return value;
    }

    public void setRightChild(KeyValPair<V> r){
        rightchild=r;
    }

    public KeyValPair<V> getRightChild(KeyValPair<V> r){
        return rightchild;
    }

    public void setLeftChild(KeyValPair<V> l){
        leftchild=l;
    }

    public KeyValPair<V> getLeftChild(KeyValPair<V> l){
        return leftchild;
    }

    @Override
    public int compareTo(KeyValPair<V> toComp) {
        if(this.getValue().compareTo(toComp.getValue())>0){
            return -1;
        }else if(this.getValue().compareTo(toComp.getValue())==0){
            return 0;
        }else{
            return 1;
        }
    }

}

compareTo 中的 if 语句不被接受,我认为这是因为我覆盖了compareTo,但是我应该如何比较泛型?

还尝试了Comparable 而不是K,结果相同。

最好的问候

编辑:编译器说什么:这一行有多个标记 - Comparable 类型中的方法 compareTo(capture#1-of ?) 不适用于参数 (Comparable) - 行断点:KeyValPair [line: 39] - compareTo(KeyValPair)

EDIT2:

更新代码:

public class KeyValPair{

private int key;
private Comparable<?> value;
private KeyValPair leftchild;
private KeyValPair rightchild;

public KeyValPair(int k,Comparable<?> v){
    key=k;
    value=v;
}

public Comparable<?> getKey(){
    return key;
}

public Comparable<?> getValue(){
    return value;
}

public void setRightChild(KeyValPair r){
    rightchild=r;
}

public KeyValPair getRightChild(KeyValPair r){
    return rightchild;
}

public void setLeftChild(KeyValPair l){
    leftchild=l;
}

public KeyValPair getLeftChild(KeyValPair l){
    return leftchild;
}

}

现在我更新了 KEYVALPAIR 的代码,但是如果我用我的 BST 类和方法加法器作为示例对其进行测试:

private void adder(KeyValPair current,KeyValPair toInsert) {
    if(toInsert.getValue().compareTo(current.getValue())>0){
        //dosomething
    }
}

它抛出: Comparable 类型中的 compareTo(capture#2-of ?) 方法不适用于 论据(可比)

解决方案:

我通过将 KEYVALPAIR 作为 BST 的内部类并使用 V 扩展 Comparable 来解决它。 现在可以使用,感谢您的帮助。

【问题讨论】:

  • “不被接受”是什么意思?编译器到底在告诉你什么?
  • “compareTo 中的 if 语句不被接受”是什么意思?我怀疑 getValue 应该返回类型 V 顺便说一句。
  • 这一行有多个标记 - Comparable 类型中的方法 compareTo(capture#1-of ?) 不适用于参数 (Comparable) - 行断点:KeyValPair [line: 39] - compareTo(KeyValPair)

标签: java generics binary-search-tree comparable compareto


【解决方案1】:

您不需要将键或值强制转换为可比较的,因为V 已经要求具有可比较性。这样做只会让你的类更难使用,因为现在你只有一个 Comparable 而不是可用的值或键。

public int getKey() {
    return key;
}

public V getValue() {
    return value;
}

@Override
public int compareTo(KeyValPair<V> toComp) {
    return -this.getValue().compareTo(toComp.getValue());
}

你还应该考虑放宽V必须实现Comparable&lt;V&gt;的要求

class KeyValPair<V extends Comparable<? super V>>

将允许例如像 Apple extends Fruit implements Comparable&lt;Fruit&gt; 这样的类 - 如果它们与超类型相当,它们仍然可以被订购。

【讨论】:

    【解决方案2】:

    您的问题是您需要将V 与另一个V 进行比较,而您对其运行时类型一无所知。

    它可以是StringInteger,您显然不会以相同的方式比较它们。

    所以我认为你的KeyValPair 不应该实现Comparable,因为它的成员(V 实例)已经这样做了:&lt;V extends Comparable&lt;V&gt;&gt;

    如果您想进行比较,您可以简单地执行以下操作:

    leftChild.getValue().compareTo(rightChild.getValue());
    

    getValue() 也应该返回Comparable&lt;V&gt;,通配符不是必需的。

    【讨论】:

    • 好的,我删除了工具和@Override,但是我怎样才能创建一个有效的 compareTo 方法呢?如果我从不进行类型转换,我永远不知道如何比较,但泛型的含义是它们不必进行类型转换?我应该为每种类型实现 compareTo 方法还是你有什么建议?顺便说一句
    • 重点是您不必知道如何比较,因为V 实例会知道您只需对它们调用compareTo。他们已经是Comparable
    • 好的,我想我明白了,我更新了代码(见问题),但现在我遇到了另一个类 BST 的新问题
    猜你喜欢
    • 2012-08-27
    • 1970-01-01
    • 2021-02-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多