将对象转换为<T>类型

4

我正在将List接口实现到一个类中,该类将数据存储在类型的数组中。这会导致使用以Collection为参数的方法时出现问题,因为collection将其对象存储为Object。如何将Object转换为T?简单的强制转换是行不通的。

class MyCollection<T> implements List<T>{
    T[] tab;

    MyCollection() {
        this.tab = (T[])new Object[10];
    }

    public boolean addAll(Collection c){
        for(Object o : c){
            o = (T)o;
            for(int i = 0; i < tab.length; i++){
                tab[i] = o;
            }
        }
    }

}

我正在尝试:

public boolean addAll(Collection<? extends T> c)

但是它会出现以下错误:

public boolean retainAll(Collection<?> c) 因为我无法在此更改集合类型 :/

public boolean retainAll(Collection<?> c){
    boolean result = false;
    for(T t : c){
    }
    return result;
}

你是如何实现 retainAll(Coll...) 的? - Adeel Ansari
3个回答

1
你应该像这样定义你的addAll方法:
public boolean addAll(Collection<? extends T> c) {...}

这就是在Java API中定义的方式


如果 retainAll 给你带来麻烦,你应该重写 retainAll 方法,同时接受 Collection<? extends T>。其他建议也可以解决问题,但在我看来,这个更加正确。 - Justin Standard

1

不需要将类型转换为T来实现retainAll(...)。例如:

public boolean retainAll(Collection<?> c){
    boolean result = false;
    Iterator<T> it = this.iterator();
    while (it.hasNext()) {
        T t : it.next();
        if (!c.contains(t)) {
            it.remove();
            result = true;
        }
    }
    return result;
}

1
这是正确的方法吗?是的,那是正确的方法。这就是接口的定义(除了接口使用E,但这并不重要)。请注意,您的addAll应返回一个布尔值。此外,您不需要在已实现的addAll中进行强制转换。改变您的循环即可。
   for(T o : c){...}

你的retainAll也应该没问题,只要返回一个boolean

编辑:

对于你的retainAll实现,没有必要迭代传入的Collection<?>并转换为T。 可以考虑迭代你的tab后备数组,并查看每个实例是否包含在传入的Collection<?>c中。 如果出于某种原因你绝对需要将c中的项目用作T,则可以进行强制类型转换。


在使用 retainAll 方法时,我遇到了“不兼容的类型。需要 T,但发现了 java.lang.Object” 的问题。 - mastodon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接