简体   繁体   中英

Implement remove(Object o) in generic collection

I am writing a generic collection based on a binary tree model.

class MyTree <T extends Comparable<T>> extends AbstractCollection<T>{...}

The underlying Node<T> class (among others) contains the following methods:

public Node<T> getLeft()  // left Node
public Node<T> getRight() // right Node
public T getValue()       // value stored in the Node

I want to override the method boolean contains(Object o) of the interface AbstractCollection<T> to have the possibility to check for Object 's of a type other than T .

For the tree traversal in O(log n) the generic type T must implement Comparable<T> , so it has the method compareTo(T t) .

My code:

@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;
}

The problem is that I can not just cast Object o to T t for using compareTo(T t) . Technically the Object 's are castable to T , but as T is a generic type, I get this warning:

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

Can someone either

  1. confirm that I can safely ignore the warning using @SuppressWarnings("unchecked") ,
  2. suggest how I can safely cast Object to T ,
  3. explain why neither of the points above can be satisfied so I can stop thinking about how to make this work?

Thanks a lot!

If you would like to have unrestricted searches, you need to do a cast. You can add instanceof to guard the cast from exceptions, but that is not ideal either.

Consider changing the bounds of T as follows:

class MyTree <T extends Comparable<? super T>> extends AbstractCollection<T>{...}

Since you do an override, suppressing the warning is pretty much required. The cast should look as follows:

@SuppressWarnings("unchecked")
Comparable<? super T> t = (Comparable<? super T>) o;

See the source of getEntry method of java.util.TreeMap for an example of how it is done in Java source (they do it for the same reason - the need to override a method with a signature taking Object ).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM