【发布时间】:2018-10-27 02:39:47
【问题描述】:
我正在编写一个基于二叉树模型的通用集合。
class MyTree <T extends Comparable<T>> extends AbstractCollection<T>{...}
底层Node<T> 类(以及其他)包含以下方法:
public Node<T> getLeft() // left Node
public Node<T> getRight() // right Node
public T getValue() // value stored in the Node
我想重写接口AbstractCollection<T> 的方法boolean contains(Object o) 以便能够检查Object 的类型不是T。
对于 O(log n) 中的树遍历,泛型类型 T 必须实现 Comparable<T>,因此它具有方法 compareTo(T t)。
我的代码:
@Override
public boolean contains(Object o){
T t = (T) o; // produces warning (see below)
BSNode<T> currentNode = this.root;
while(currentNode != null){
if(currentNode.getValue().equals(o)) {return true;}
if(currentNode.getValue().compareTo(t) < 0) {currentNode = currentNode.getRight();}
if(currentNode.getValue().compareTo(t) > 0) {currentNode = currentNode.getLeft();}
}
return false;
}
问题是我不能只将Object o 转换为T t 以使用compareTo(T t)。从技术上讲,Object 可以转换为T,但由于T 是泛型类型,我会收到以下警告:
warning: [unchecked] unchecked cast
T t = (T) o;
^
required: T
found: Object
where T is a type-variable:
T extends Comparable<T> declared in class MyTree
有人可以吗
- 确认我可以使用
@SuppressWarnings("unchecked")安全地忽略警告, - 建议我如何安全地将
Object转换为T, - 请解释为什么以上两点都不能满足,这样我就可以停止思考如何完成这项工作?
非常感谢!
【问题讨论】:
-
我不认为 Object 可以安全地转换为 T ,因为它可能不是 T 类型的对象,而是其他类型的对象。另外,如果您要定义 T 类型的集合,为什么要将 Object 传递给您的
contains()? -
不相关: 不要调用
equals一次和compareTo两次,只需调用compareTo一次:int cmp = currentNode.getValue().compareTo(t); if (cmp == 0) { return true; } currentNode = (cmp < 0 ? currentNode.getRight() : currentNode.getLeft());--- 记住,equals和 @ 987654349@ 可能是相对昂贵的电话。 -
@Andreas 我实际上计划在一切正常后执行此操作。这里没有展示
equals(Object o)和compareTo(T)的不同参数类型,也不是为了展示该方法在不添加那一小层抽象的情况下应该如何工作。无论如何感谢您的建议。 :) -
@LuisMuñoz 通常可以将
Object o转换为T t,因为Object.equals(Object o)并不严格禁止不同类型的Object相等。这就是AbstractCollection实现contains(Object o)的原因。另见here
标签: java generics collections comparable