java - 转换 Integer -> Object 和后来的 Object -> Integer
问题描述
下面是 AVL 树实现的代码片段。过去它工作得很好,但现在它不再工作了。原因似乎是将 Object 转换为 Integer。
因此 Avl 结构将 Object 作为数据处理,而用户(在本例中为 main() )进行转换。我想要实现的是具有可比较对象的通用 AVL 树。实际上,我将对象与一个键一起插入,以便能够区分要排序的内容。它们在内部被放置在一个名为 KeyData 的本地类中。
这是代码:
// private stuff above - not interesting for problem
// Public AVL tree methods
public void insert(Object thedata, String thekey) {
internal_insert(new KeyData(thedata, thekey));
}
public Object find(String key) {
Object ret = null;
KeyData x = new KeyData(null, key);
if(data != null) {
if(x.compareTo(data) == 0)
ret = data;
else if(x.compareTo(data) < 0) {
if(left != null)
ret = left.find(key);
} else {
if(right != null)
ret = right.find(key);
}
}
return ret;
}
public Object[] inorder() {
Vector<Object> v = new Vector<Object>();
iinorder(v);
return v.toArray();
}
public static void main(String[] args) {
Avl test = new Avl();
test.insert(Integer.valueOf(1090), "1");
test.insert(Integer.valueOf(343452), "2");
test.insert(Integer.valueOf(3345), "3");
//Object t2 = test.find("2");
Object lookfor = test.find("2");
Integer t2 = (Integer) lookfor; // Line 164
System.out.println("Got: " + t2.toString());
}
结果如下:
$ java Avl
Exception in thread "main" java.lang.ClassCastException:
class Avl$KeyData cannot be cast to class java.lang.Integer (Avl$KeyData is in unnamed module of loader 'app'; java.lang.Integer is in module java.base of loader 'bootstrap')
at Avl.main(Avl.java:164)
……那是什么故事?
解决方案
……那是什么故事?
简短的版本是您的find
方法不返回Integer
值。因此,您不能将其转换为Integer
.
过去它工作得很好,但现在它不再工作了。
好吧,从那时到现在,您的代码中一定发生了重大变化。(提示:Java 语言或其实现并没有以导致这种情况的方式发生变化!)
所以让我们看看你的find
方法。
public Object find(String key) {
Object ret = null;
KeyData x = new KeyData(null, key);
if (data != null) {
if (x.compareTo(data) == 0)
ret = data;
else if (x.compareTo(data) < 0) {
if (left != null)
ret = left.find(key);
} else {
if (right != null)
ret = right.find(key);
}
}
return ret;
}
第一个观察是你的方法的原始缩进是一团糟。糟糕的缩进让你的代码很难让每个人都阅读......和理解。我已经修好了。
所以该find
方法是递归地搜索一棵树,并在找到匹配项时。它返回任何data
内容。我看不到该Data
字段的声明,但有证据表明它是Avl.KeyData
. (这是有道理的......因为您将data
其与x
哪个KeyData
实例进行比较。)
无论如何,这解释了为什么结果不是Integer
.
你还没有向我们展示这个KeyData
类,但我猜它有一个value
字段是 / 应该是一个Integer
. 这就是你应该返回的。找到KeyData
的对象的值字段的内容。
但这里最大的问题是你使用Object
. 正如@NomadMaker 评论的那样,这应该是一个具有类型参数的泛型类型,该类型参数将是树中值的类型。然后您不必在main
... 中使用类型转换,编译器会告诉您find
返回 aKeyData<V>
而不是 a是不正确的V
。
(您的实施还有一些其他问题......但这不是“诊所”。)