【问题标题】:Cannot cast Object to Comparable无法将对象转换为 Comparable
【发布时间】:2015-02-04 20:34:17
【问题描述】:

我正在尝试对二叉搜索树进行排序,并将其值存储在数组中,但是当我尝试将 ArrayList 转换为数组时,它说我无法将 Object 转换为 Comparable。

@Override
public T[] postOrder() {
    ArrayList<T> array = new ArrayList<T>();
    postOrder(root, array);
    return (T[]) array.toArray();
}

private void postOrder(BSTNode<T> currRoot, ArrayList<T> array) {
    if (currRoot == null)
        return;
    if (!currRoot.getLeft().isEmpty())
        postOrder((BSTNode<T>) currRoot.getLeft(), array);
    if (!currRoot.getRight().isEmpty())
        postOrder((BSTNode<T>) currRoot.getRight(), array);
    array.add(currRoot.getData());
}

错误信息: 线程“main”中的异常 java.lang.ClassCastException: [Ljava.lang.Object;不能转换为 [Ljava.lang.Comparable;

编辑:这样解决了

public T[] postOrder() {
    ArrayList<T> array = new ArrayList<T>();
    postOrder(root, array);
    return array.toArray((T[]) Array.newInstance(root.getData().getClass(), size()));
}

【问题讨论】:

    标签: java arrays casting comparable


    【解决方案1】:

    [Ljava.lang.Object;不能转换为 [Ljava.lang.Comparable;

    这意味着您正在尝试将Object[] 转换为Comparable[]。 (“[L”表示数组。)

    toArray 返回Object[]。您也许可以改用&lt;T&gt;toArray(T[]);但是,由于type erasure,您不能这样做

    //                  cannot do
    //                    vvvvv
    return array.toArray( new T[ mySize ] );
    

    所以

    • 您的树需要Class&lt;T&gt;
    • 调用者需要传递一个T[]来填充。
    • postOrder 需要返回一个非泛型数组。 (Object[]...Comparable[]...)
    • 您应该返回 List&lt;T&gt; 而不是 T[]

    我注意到您正在使用@Override,因此您的超类型(接口、超类)可能有关于如何实现此方法的说明。 (即,如果这是家庭作业,您应该询问您的导师,因为我不清楚您应该使用哪种解决方案。)

    如果你碰巧有Class&lt;T&gt;,那么你可以这样做

    @Override
    public T[] postOrder() {
        ArrayList<T> array = new ArrayList<T>();
        postOrder(root, array);
        return (T[]) array.toArray(
            java.lang.reflect.Array.newInstance(myClassT, array.size())
        );
    }
    

    否则需要更改方法的签名。

    另见

    【讨论】:

    • 非常详细的解释,但没有解决方案......我的正好相反:)
    • @TWiStErRob OP 正在使用@Override,因此他们显然无法更改方法签名。就我个人而言,我不确定要告诉他们什么。
    • 我在我的代码中使用@Override,但我也定义了接口。即使他不能修改接口,也可以像您引用的问题一样在构造函数中传递Class&lt;T&gt; 实例!
    • @TWiStErRob 没错,它可能是 OP 自己的接口。
    【解决方案2】:

    泛型数组比较乱,需要调用另一个toArray()方法:

    public T[] postOrder(T[] result) {
        ArrayList<T> array = new ArrayList<T>();
        postOrder(root, array);
        return array.toArray(result);
    }
    

    结果的大小无关紧要,只要确保以后不要使用传入的内容,因为如果大小不正确,它可能会在 toArray 中重新分配,所以只使用返回值postOrder.

    考虑一下,如果您只返回List&lt;T&gt;,并让调用者负责将其转换为数组,它可能会更干净!请注意返回 List 所需的解释要少得多...

    public List<T> postOrder() {
        ArrayList<T> array = new ArrayList<T>();
        postOrder(root, array);
        return array;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-09-26
      • 2019-07-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-24
      相关资源
      最近更新 更多